Make sure bitpiece not generated that covers the entire variable (#3223)

This commit is contained in:
Adam Yang 2020-10-28 17:26:54 -07:00 коммит произвёл GitHub
Родитель c607bb3c03
Коммит 99840a506f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 73 добавлений и 0 удалений

Просмотреть файл

@ -28,6 +28,7 @@
#include "llvm/Analysis/PostDominators.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/PassManager.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/Pass.h"
@ -439,6 +440,9 @@ public:
AddFunctionAnnotationForInitializers(M, DM);
}
// Fix DIExpression fragments that cover whole variables
LegalizeDbgFragments(M);
return true;
}
@ -481,6 +485,55 @@ private:
}
}
static bool BitPieceCoversEntireVar(DIExpression *expr, DILocalVariable *var, DITypeIdentifierMap &TypeIdentifierMap) {
if (expr->isBitPiece()) {
DIType *ty = var->getType().resolve(TypeIdentifierMap);
return expr->getBitPieceOffset() == 0 && expr->getBitPieceSize() == ty->getSizeInBits();
}
return false;
}
static void LegalizeDbgFragmentsForDbgIntrinsic(Function *f, DITypeIdentifierMap &TypeIdentifierMap) {
Intrinsic::ID intrinsic = f->getIntrinsicID();
DIBuilder dib(*f->getParent());
if (intrinsic == Intrinsic::dbg_value) {
for (auto it = f->user_begin(), end = f->user_end(); it != end;) {
User *u = *(it++);
DbgValueInst *di = cast<DbgValueInst>(u);
DIExpression *expr = di->getExpression();
DILocalVariable *var = di->getVariable();
if (BitPieceCoversEntireVar(expr, var, TypeIdentifierMap)) {
dib.insertDbgValueIntrinsic(di->getValue(), 0, var, DIExpression::get(di->getContext(), {}), di->getDebugLoc(), di);
di->eraseFromParent();
}
}
}
else if (intrinsic == Intrinsic::dbg_declare) {
for (auto it = f->user_begin(), end = f->user_end(); it != end;) {
User *u = *(it++);
DbgDeclareInst *di = cast<DbgDeclareInst>(u);
DIExpression *expr = di->getExpression();
DILocalVariable *var = di->getVariable();
if (BitPieceCoversEntireVar(expr, var, TypeIdentifierMap)) {
dib.insertDeclare(di->getAddress(), var, DIExpression::get(di->getContext(), {}), di->getDebugLoc(), di);
di->eraseFromParent();
}
}
}
}
static void LegalizeDbgFragments(Module &M) {
DITypeIdentifierMap TypeIdentifierMap;
if (Function *f = M.getFunction(Intrinsic::getName(Intrinsic::dbg_value))) {
LegalizeDbgFragmentsForDbgIntrinsic(f, TypeIdentifierMap);
}
if (Function *f = M.getFunction(Intrinsic::getName(Intrinsic::dbg_declare))) {
LegalizeDbgFragmentsForDbgIntrinsic(f, TypeIdentifierMap);
}
}
void RemoveStoreUndefOutput(Module &M, hlsl::OP *hlslOP) {
for (iplist<Function>::iterator F : M.getFunctionList()) {
if (!hlslOP->IsDxilOpFunc(F))

Просмотреть файл

@ -0,0 +1,20 @@
// RUN: %dxc -Zi -Od -E main -T ps_6_0 %s | FileCheck %s
// Regression test for structs with just a single 32-bit member.
// CHECK-DAG: call void @llvm.dbg.value(metadata float %{{.*}}, i64 0, metadata !{{[0-9]+}}, metadata !{{[0-9]+}}), !dbg !{{[0-9]+}} ; var:"my_s" !DIExpression()
// Exclude quoted source file (see readme)
// CHECK-LABEL: {{!"[^"]*\\0A[^"]*"}}
struct MyStruct {
float1 foo;
};
[RootSignature("")]
float main(float a : A) : SV_Target {
MyStruct my_s;
my_s.foo.x = a;
return my_s.foo.x;
}