Index: lib/CodeGen/AsmPrinter/DwarfExpression.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -342,6 +342,7 @@ case dwarf::DW_OP_minus: case dwarf::DW_OP_mul: case dwarf::DW_OP_or: + case dwarf::DW_OP_xor: emitOp(Op->getOp()); break; case dwarf::DW_OP_deref: Index: lib/IR/DebugInfoMetadata.cpp =================================================================== --- lib/IR/DebugInfoMetadata.cpp +++ lib/IR/DebugInfoMetadata.cpp @@ -709,6 +709,7 @@ case dwarf::DW_OP_minus: case dwarf::DW_OP_mul: case dwarf::DW_OP_or: + case dwarf::DW_OP_xor: case dwarf::DW_OP_deref: case dwarf::DW_OP_xderef: break; Index: lib/Transforms/Utils/Local.cpp =================================================================== --- lib/Transforms/Utils/Local.cpp +++ lib/Transforms/Utils/Local.cpp @@ -1536,17 +1536,27 @@ for (auto *DII : DbgUsers) applyOffset(DII, Offset.getSExtValue()); } else if (auto *BI = dyn_cast(&I)) { - if (BI->getOpcode() == Instruction::Add || - BI->getOpcode() == Instruction::Or) - if (auto *ConstInt = dyn_cast(I.getOperand(1))) - if (ConstInt->getBitWidth() <= 64) { - uint64_t Val = ConstInt->getSExtValue(); - for (auto *DII : DbgUsers) - if (BI->getOpcode() == Instruction::Add) - applyOffset(DII, Val); - else if (BI->getOpcode() == Instruction::Or) - applyOps(DII, {dwarf::DW_OP_constu, Val, dwarf::DW_OP_or}); - } + auto *ConstInt = dyn_cast(I.getOperand(1)); + if (!ConstInt || ConstInt->getBitWidth() > 64) + return; + + uint64_t Val = ConstInt->getSExtValue(); + for (auto *DII : DbgUsers) { + switch (BI->getOpcode()) { + case Instruction::Add: + applyOffset(DII, Val); + break; + case Instruction::Or: + applyOps(DII, {dwarf::DW_OP_constu, Val, dwarf::DW_OP_or}); + break; + case Instruction::Xor: + applyOps(DII, {dwarf::DW_OP_constu, Val, dwarf::DW_OP_xor}); + break; + default: + // TODO: Salvage constants from each kind of binop we know about. + continue; + } + } } else if (isa(&I)) { MetadataAsValue *AddrMD = wrapMD(I.getOperand(0)); for (auto *DII : DbgUsers) { Index: test/Transforms/InstCombine/debuginfo-variables.ll =================================================================== --- test/Transforms/InstCombine/debuginfo-variables.ll +++ test/Transforms/InstCombine/debuginfo-variables.ll @@ -17,6 +17,13 @@ ret void } +define void @test_xor(i32 %A) { +; CHECK-LABEL: @test_xor( +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 %A, metadata !22, metadata !DIExpression(DW_OP_constu, 1, DW_OP_xor, DW_OP_stack_value)), !dbg !23 + %xor = xor i32 %A, 1 + ret void +} + ; CHECK: !8 = !DILocalVariable(name: "1", scope: !5, file: !1, line: 1, type: !9) ; CHECK: !10 = !DILocalVariable(name: "2", scope: !5, file: !1, line: 2, type: !11) ; CHECK: !12 = !DILocation(line: 2, column: 1, scope: !5) @@ -24,3 +31,6 @@ ; CHECK: !17 = !DILocalVariable(name: "3", scope: !15, file: !1, line: 4, type: !11) ; CHECK: !18 = !DILocation(line: 4, column: 1, scope: !15) + +; CHECK: !22 = !DILocalVariable(name: "4", scope: !20, file: !1, line: 6, type: !9) +; CHECK: !23 = !DILocation(line: 6, column: 1, scope: !20)