diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index 229ee2bd0164c..9bd1d7880c9f8 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -1881,7 +1881,8 @@ DIExpression *DIExpression::append(const DIExpression *Expr, Op.appendToVector(NewOps); } NewOps.append(Ops.begin(), Ops.end()); - auto *result = DIExpression::get(Expr->getContext(), NewOps); + auto *result = + DIExpression::get(Expr->getContext(), NewOps)->foldConstantMath(); assert(result->isValid() && "concatenated expression is not valid"); return result; } diff --git a/llvm/test/Bitcode/upgrade-dbg-addr.ll b/llvm/test/Bitcode/upgrade-dbg-addr.ll index 06a411c2c8348..de35609713f93 100644 --- a/llvm/test/Bitcode/upgrade-dbg-addr.ll +++ b/llvm/test/Bitcode/upgrade-dbg-addr.ll @@ -9,7 +9,7 @@ entry: %num.addr = alloca i32, align 4 store i32 %num, ptr %num.addr, align 4 ; CHECK-NOT: call void @llvm.dbg.addr - ; CHECK: call void @llvm.dbg.value(metadata ptr %num.addr, metadata ![[#]], metadata !DIExpression(DW_OP_plus_uconst, 0, DW_OP_deref)) + ; CHECK: call void @llvm.dbg.value(metadata ptr %num.addr, metadata ![[#]], metadata !DIExpression(DW_OP_deref)) call void @llvm.dbg.addr(metadata ptr %num.addr, metadata !16, metadata !DIExpression(DW_OP_plus_uconst, 0)), !dbg !17 %0 = load i32, ptr %num.addr, align 4 ret i32 %0 diff --git a/llvm/test/DebugInfo/MIR/AArch64/dbgcall-site-expr-chain.mir b/llvm/test/DebugInfo/MIR/AArch64/dbgcall-site-expr-chain.mir index cb3e780664404..02f4ce1200ca1 100644 --- a/llvm/test/DebugInfo/MIR/AArch64/dbgcall-site-expr-chain.mir +++ b/llvm/test/DebugInfo/MIR/AArch64/dbgcall-site-expr-chain.mir @@ -105,7 +105,7 @@ body: | # CHECK: DW_TAG_GNU_call_site_parameter # CHECK-NEXT: DW_AT_location (DW_OP_reg2 W2) -# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg19 W19+700, DW_OP_plus_uconst 0x9, DW_OP_plus_uconst 0x50) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg19 W19+789) # CHECK: DW_TAG_GNU_call_site_parameter # CHECK-NEXT: DW_AT_location (DW_OP_reg1 W1) @@ -113,4 +113,4 @@ body: | # CHECK: DW_TAG_GNU_call_site_parameter # CHECK-NEXT: DW_AT_location (DW_OP_reg0 W0) -# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg19 W19+100, DW_OP_plus_uconst 0x17) +# CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg19 W19+123) diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp index 9647ac8c43966..3f766a414f08f 100644 --- a/llvm/unittests/IR/MetadataTest.cpp +++ b/llvm/unittests/IR/MetadataTest.cpp @@ -3610,6 +3610,144 @@ TEST_F(DIExpressionTest, Fold) { EXPECT_EQ(E, ResExpr); } +TEST_F(DIExpressionTest, Append) { + // Test appending a {dwarf::DW_OP_constu, , DW_OP_plus} to a DW_OP_plus + // expression + SmallVector Ops = {dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_constu, + 2, dwarf::DW_OP_plus}; + auto *Expr = DIExpression::get(Context, Ops); + SmallVector AppendOps = {dwarf::DW_OP_constu, 3, + dwarf::DW_OP_plus}; + auto *AppendExpr = DIExpression::append(Expr, AppendOps); + SmallVector OpsRes = {dwarf::DW_OP_LLVM_arg, 0, + dwarf::DW_OP_plus_uconst, 5}; + auto *ResExpr = DIExpression::get(Context, OpsRes); + EXPECT_EQ(ResExpr, AppendExpr); + + // Test appending a {dwarf::DW_OP_plus_uconst, } to a DW_OP_plus + // expression uint64_t PlusUConstOps[] = {dwarf::DW_OP_plus_uconst, 3}; + AppendOps.clear(); + AppendOps.push_back(dwarf::DW_OP_plus_uconst); + AppendOps.push_back(3); + AppendExpr = DIExpression::append(Expr, AppendOps); + OpsRes.clear(); + OpsRes.push_back(dwarf::DW_OP_LLVM_arg); + OpsRes.push_back(0); + OpsRes.push_back(dwarf::DW_OP_plus_uconst); + OpsRes.push_back(5); + ResExpr = DIExpression::get(Context, OpsRes); + EXPECT_EQ(ResExpr, AppendExpr); + + // Test appending a {dwarf::DW_OP_constu, 0, DW_OP_plus} to an expression + AppendOps.clear(); + AppendOps.push_back(dwarf::DW_OP_constu); + AppendOps.push_back(0); + AppendOps.push_back(dwarf::DW_OP_plus); + AppendExpr = DIExpression::append(Expr, AppendOps); + OpsRes.clear(); + OpsRes.push_back(dwarf::DW_OP_LLVM_arg); + OpsRes.push_back(0); + OpsRes.push_back(dwarf::DW_OP_plus_uconst); + OpsRes.push_back(2); + ResExpr = DIExpression::get(Context, OpsRes); + EXPECT_EQ(ResExpr, AppendExpr); + + // Test appending a {dwarf::DW_OP_constu, 0, DW_OP_minus} to an expression + AppendOps.clear(); + AppendOps.push_back(dwarf::DW_OP_constu); + AppendOps.push_back(0); + AppendOps.push_back(dwarf::DW_OP_minus); + AppendExpr = DIExpression::append(Expr, AppendOps); + OpsRes.clear(); + OpsRes.push_back(dwarf::DW_OP_LLVM_arg); + OpsRes.push_back(0); + OpsRes.push_back(dwarf::DW_OP_plus_uconst); + OpsRes.push_back(2); + ResExpr = DIExpression::get(Context, OpsRes); + EXPECT_EQ(ResExpr, AppendExpr); + + // Test appending a {dwarf::DW_OP_constu, 0, DW_OP_shl} to an expression + AppendOps.clear(); + AppendOps.push_back(dwarf::DW_OP_constu); + AppendOps.push_back(0); + AppendOps.push_back(dwarf::DW_OP_shl); + AppendExpr = DIExpression::append(Expr, AppendOps); + OpsRes.clear(); + OpsRes.push_back(dwarf::DW_OP_LLVM_arg); + OpsRes.push_back(0); + OpsRes.push_back(dwarf::DW_OP_plus_uconst); + OpsRes.push_back(2); + ResExpr = DIExpression::get(Context, OpsRes); + EXPECT_EQ(ResExpr, AppendExpr); + + // Test appending a {dwarf::DW_OP_constu, 0, DW_OP_shr} to an expression + AppendOps.clear(); + AppendOps.push_back(dwarf::DW_OP_constu); + AppendOps.push_back(0); + AppendOps.push_back(dwarf::DW_OP_shr); + AppendExpr = DIExpression::append(Expr, AppendOps); + OpsRes.clear(); + OpsRes.push_back(dwarf::DW_OP_LLVM_arg); + OpsRes.push_back(0); + OpsRes.push_back(dwarf::DW_OP_plus_uconst); + OpsRes.push_back(2); + ResExpr = DIExpression::get(Context, OpsRes); + EXPECT_EQ(ResExpr, AppendExpr); + + // Test appending a {dwarf::DW_OP_constu, , DW_OP_mul} to a DW_OP_mul + // expression + Ops.clear(); + Ops.push_back(dwarf::DW_OP_LLVM_arg); + Ops.push_back(0); + Ops.push_back(dwarf::DW_OP_constu); + Ops.push_back(2); + Ops.push_back(dwarf::DW_OP_mul); + Expr = DIExpression::get(Context, Ops); + AppendOps.clear(); + AppendOps.push_back(dwarf::DW_OP_constu); + AppendOps.push_back(3); + AppendOps.push_back(dwarf::DW_OP_mul); + AppendExpr = DIExpression::append(Expr, AppendOps); + OpsRes.clear(); + OpsRes.push_back(dwarf::DW_OP_LLVM_arg); + OpsRes.push_back(0); + OpsRes.push_back(dwarf::DW_OP_constu); + OpsRes.push_back(6); + OpsRes.push_back(dwarf::DW_OP_mul); + ResExpr = DIExpression::get(Context, OpsRes); + EXPECT_EQ(ResExpr, AppendExpr); + + // Test appending a {dwarf::DW_OP_constu, 1, DW_OP_mul} to an expression + AppendOps.clear(); + AppendOps.push_back(dwarf::DW_OP_constu); + AppendOps.push_back(1); + AppendOps.push_back(dwarf::DW_OP_mul); + AppendExpr = DIExpression::append(Expr, AppendOps); + OpsRes.clear(); + OpsRes.push_back(dwarf::DW_OP_LLVM_arg); + OpsRes.push_back(0); + OpsRes.push_back(dwarf::DW_OP_constu); + OpsRes.push_back(2); + OpsRes.push_back(dwarf::DW_OP_mul); + ResExpr = DIExpression::get(Context, OpsRes); + EXPECT_EQ(ResExpr, AppendExpr); + + // Test appending a {dwarf::DW_OP_constu, 1, DW_OP_div} to an expression + AppendOps.clear(); + AppendOps.push_back(dwarf::DW_OP_constu); + AppendOps.push_back(1); + AppendOps.push_back(dwarf::DW_OP_div); + AppendExpr = DIExpression::append(Expr, AppendOps); + OpsRes.clear(); + OpsRes.push_back(dwarf::DW_OP_LLVM_arg); + OpsRes.push_back(0); + OpsRes.push_back(dwarf::DW_OP_constu); + OpsRes.push_back(2); + OpsRes.push_back(dwarf::DW_OP_mul); + ResExpr = DIExpression::get(Context, OpsRes); + EXPECT_EQ(ResExpr, AppendExpr); +} + TEST_F(DIExpressionTest, isValid) { #define EXPECT_VALID(...) \ do { \