@@ -1123,7 +1123,8 @@ MDNode *SPIRVToLLVMDbgTran::transGlobalVariable(const SPIRVExtInst *DebugInst) {
1123
1123
StringRef LinkageName = getString (Ops[LinkageNameIdx]);
1124
1124
1125
1125
DIDerivedType *StaticMemberDecl = nullptr ;
1126
- if (Ops.size () > MinOperandCount) {
1126
+ if (Ops.size () > MinOperandCount &&
1127
+ !getDbgInst<SPIRVDebug::DebugInfoNone>(Ops[StaticMemberDeclarationIdx])) {
1127
1128
StaticMemberDecl = transDebugInst<DIDerivedType>(
1128
1129
BM->get <SPIRVExtInst>(Ops[StaticMemberDeclarationIdx]));
1129
1130
}
@@ -1135,13 +1136,18 @@ MDNode *SPIRVToLLVMDbgTran::transGlobalVariable(const SPIRVExtInst *DebugInst) {
1135
1136
if (getDbgInst<SPIRVDebug::Expression>(Ops[VariableIdx]))
1136
1137
DIExpr =
1137
1138
transDebugInst<DIExpression>(BM->get <SPIRVExtInst>(Ops[VariableIdx]));
1139
+ else if (Ops.size () > DIOpBasedExprIdx)
1140
+ DIExpr = transDebugInst<DIExpression>(
1141
+ BM->get <SPIRVExtInst>(Ops[DIOpBasedExprIdx]));
1138
1142
1139
1143
SPIRVWord Flags =
1140
1144
getConstantValueOrLiteral (Ops, FlagsIdx, DebugInst->getExtSetKind ());
1141
1145
bool IsLocal = Flags & SPIRVDebug::FlagIsLocal;
1142
1146
bool IsDefinition = Flags & SPIRVDebug::FlagIsDefinition;
1143
1147
MDNode *VarDecl = nullptr ;
1144
1148
if (IsDefinition) {
1149
+ if (DIExpr && DIExpr->holdsNewElements () && !DIExpr->isValid ())
1150
+ DIExpr = DIExpr->getPoisoned ();
1145
1151
VarDecl = getDIBuilder (DebugInst).createGlobalVariableExpression (
1146
1152
Parent, Name, LinkageName, File, LineNo, Ty, IsLocal, IsDefinition,
1147
1153
DIExpr, StaticMemberDecl);
@@ -1156,7 +1162,7 @@ MDNode *SPIRVToLLVMDbgTran::transGlobalVariable(const SPIRVExtInst *DebugInst) {
1156
1162
1157
1163
// Ops[VariableIdx] was not used to hold an Expression with the initial value
1158
1164
// for the GlobalVariable
1159
- if (!DIExpr) {
1165
+ if (!DIExpr || Ops. size () > DIOpBasedExprIdx ) {
1160
1166
// If the variable has no initializer Ops[VariableIdx] is OpDebugInfoNone.
1161
1167
// Otherwise Ops[VariableIdx] may be a global variable or a constant(C++
1162
1168
// static const).
@@ -1406,7 +1412,84 @@ DINode *SPIRVToLLVMDbgTran::transModule(const SPIRVExtInst *DebugInst) {
1406
1412
Scope, Name, ConfigMacros, IncludePath, ApiNotes, File, Line, IsDecl);
1407
1413
}
1408
1414
1415
+ template <>
1416
+ Type *SPIRVToLLVMDbgTran::transDIOpOperand (const SPIRVExtInst *DbgOpInst,
1417
+ unsigned Idx) {
1418
+ const SPIRVWordVec &Operands = DbgOpInst->getArguments ();
1419
+ SPIRVType *Ty = BM->get <SPIRVType>(Operands[Idx]);
1420
+ return SPIRVReader->transType (Ty);
1421
+ }
1422
+
1423
+ template <>
1424
+ uint32_t SPIRVToLLVMDbgTran::transDIOpOperand (const SPIRVExtInst *DbgOpInst,
1425
+ unsigned Idx) {
1426
+ const SPIRVWordVec &Operands = DbgOpInst->getArguments ();
1427
+ return getConstantValueOrLiteral (Operands, Idx, DbgOpInst->getExtSetKind ());
1428
+ }
1429
+
1430
+ template <>
1431
+ ConstantData *
1432
+ SPIRVToLLVMDbgTran::transDIOpOperand (const SPIRVExtInst *DbgOpInst,
1433
+ unsigned Idx) {
1434
+ const SPIRVWordVec &Operands = DbgOpInst->getArguments ();
1435
+ SPIRVValue *Val = BM->get <SPIRVValue>(Operands[Idx]);
1436
+ return cast<ConstantData>(SPIRVReader->transValue (Val, nullptr , nullptr ));
1437
+ }
1438
+
1439
+ MDNode *
1440
+ SPIRVToLLVMDbgTran::tryTransDIOpDIExpression (const SPIRVExtInst *DebugInst) {
1441
+ using namespace SPIRVDebug ::Operand::Operation;
1442
+
1443
+ auto getOpcodeFromInst = [this ](const SPIRVExtInst *OpInst) {
1444
+ return static_cast <SPIRVDebug::ExpressionOpCode>(getConstantValueOrLiteral (
1445
+ OpInst->getArguments (), OpCodeIdx, OpInst->getExtSetKind ()));
1446
+ };
1447
+
1448
+ const SPIRVWordVec &Args = DebugInst->getArguments ();
1449
+
1450
+ // DIOp-based DIExpressions can't be empty.
1451
+ if (Args.empty ())
1452
+ return nullptr ;
1453
+ const SPIRVExtInst *FirstOp = BM->get <SPIRVExtInst>(Args[0 ]);
1454
+ // Check if this is a DW_OP-based expression.
1455
+ if (getOpcodeFromInst (FirstOp) < SPIRVDebug::DIOp_Begin)
1456
+ return nullptr ;
1457
+
1458
+ std::vector<llvm::DIOp::Variant> DIOps;
1459
+ for (SPIRVId A : Args) {
1460
+ SPIRVExtInst *DbgOpInst = BM->get <SPIRVExtInst>(A);
1461
+ auto Opcode = getOpcodeFromInst (DbgOpInst);
1462
+ auto BitcodeID = SPIRV::DbgExpressionDIOpBasedOpCodeMap::rmap (Opcode);
1463
+
1464
+ #define HANDLE_OP0 (Name ) \
1465
+ case DIOp::Name::getBitcodeID (): \
1466
+ DIOps.push_back (DIOp::Name ()); \
1467
+ break ;
1468
+ #define HANDLE_OP1 (Name, OpType, OpName ) \
1469
+ case DIOp::Name::getBitcodeID (): \
1470
+ DIOps.push_back (DIOp::Name (transDIOpOperand<OpType>(DbgOpInst, 1 ))); \
1471
+ break ;
1472
+ #define HANDLE_OP2 (Name, OpType1, OpName1, OpType2, OpName2 ) \
1473
+ case DIOp::Name::getBitcodeID (): { \
1474
+ OpType1 First = transDIOpOperand<OpType1>(DbgOpInst, 1 ); \
1475
+ OpType2 Second = transDIOpOperand<OpType2>(DbgOpInst, 2 ); \
1476
+ DIOps.push_back (DIOp::Name (First, Second)); \
1477
+ break ; \
1478
+ }
1479
+
1480
+ switch (BitcodeID) {
1481
+ default :
1482
+ llvm_unreachable (" translating unknown DIOp!" );
1483
+ #include " llvm/IR/DIExprOps.def"
1484
+ }
1485
+ }
1486
+ return DIExpression::get (M->getContext (), bool (), DIOps);
1487
+ }
1488
+
1409
1489
MDNode *SPIRVToLLVMDbgTran::transExpression (const SPIRVExtInst *DebugInst) {
1490
+ if (MDNode *N = tryTransDIOpDIExpression (DebugInst))
1491
+ return N;
1492
+
1410
1493
const SPIRVWordVec &Args = DebugInst->getArguments ();
1411
1494
std::vector<uint64_t > Ops;
1412
1495
for (SPIRVId A : Args) {
@@ -1563,6 +1646,17 @@ SPIRVToLLVMDbgTran::transDebugIntrinsic(const SPIRVExtInst *DebugInst,
1563
1646
auto GetExpression = [&](SPIRVId Id) -> DIExpression * {
1564
1647
return transDebugInst<DIExpression>(BM->get <SPIRVExtInst>(Id));
1565
1648
};
1649
+ auto PoisonInvalidExpr = [&](DIExpression *Expr, DILocalVariable *Var,
1650
+ Value *Op) {
1651
+ if (!Expr->holdsNewElements ())
1652
+ return Expr;
1653
+ DIExpressionEnv Env{Var, Op, BB->getParent ()->getParent ()->getDataLayout ()};
1654
+ // FIXME: The variadic expression handling for dbg.value below is broken,
1655
+ // just poison.
1656
+ if (Expr->getNewNumLocationOperands () > 1 || !Expr->isValid (Env))
1657
+ return Expr->getPoisoned ();
1658
+ return Expr;
1659
+ };
1566
1660
SPIRVWordVec Ops = DebugInst->getArguments ();
1567
1661
switch (DebugInst->getExtOp ()) {
1568
1662
case SPIRVDebug::Scope:
@@ -1584,21 +1678,25 @@ SPIRVToLLVMDbgTran::transDebugIntrinsic(const SPIRVExtInst *DebugInst,
1584
1678
auto *AI = new AllocaInst (Type::getInt8Ty (M->getContext ()),
1585
1679
BB->getParent ()->getParent ()->getDataLayout ().getAllocaAddrSpace (),
1586
1680
" tmp" , BB);
1587
- DbgInstPtr DbgDeclare = DIB.insertDeclare (
1588
- AI, LocalVar.first , GetExpression (Ops[ExpressionIdx]),
1589
- LocalVar.second , BB);
1681
+ auto *Expr = PoisonInvalidExpr (GetExpression (Ops[ExpressionIdx]),
1682
+ LocalVar.first , AI);
1683
+ DbgInstPtr DbgDeclare =
1684
+ DIB.insertDeclare (AI, LocalVar.first , Expr, LocalVar.second , BB);
1590
1685
AI->eraseFromParent ();
1591
1686
return DbgDeclare;
1592
1687
}
1593
- return DIB.insertDeclare (GetValue (Ops[VariableIdx]), LocalVar.first ,
1594
- GetExpression (Ops[ExpressionIdx]), LocalVar.second ,
1595
- BB);
1688
+
1689
+ Value *Val = GetValue (Ops[VariableIdx]);
1690
+ auto *Expr = PoisonInvalidExpr (GetExpression (Ops[ExpressionIdx]),
1691
+ LocalVar.first , Val);
1692
+ return DIB.insertDeclare (Val, LocalVar.first , Expr, LocalVar.second , BB);
1596
1693
}
1597
1694
case SPIRVDebug::Value: {
1598
1695
using namespace SPIRVDebug ::Operand::DebugValue;
1599
1696
auto LocalVar = GetLocalVar (Ops[DebugLocalVarIdx]);
1600
1697
Value *Val = GetValue (Ops[ValueIdx]);
1601
1698
DIExpression *Expr = GetExpression (Ops[ExpressionIdx]);
1699
+ Expr = PoisonInvalidExpr (Expr, LocalVar.first , Val);
1602
1700
DbgInstPtr DbgValIntr = getDIBuilder (DebugInst).insertDbgValueIntrinsic (
1603
1701
Val, LocalVar.first , Expr, LocalVar.second , BB);
1604
1702
0 commit comments