This is a patch to fix debug value intrinsics outside of cloned blocks in the jumpthreading pass to point towards any derived values. If it cannot it sets them to undef
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
llvm/lib/Transforms/Utils/SSAUpdater.cpp | ||
---|---|---|
221 | Please use PoisonValue as placeholder whenever possible. We are trying to get rid of undef in LLVM. |
llvm/lib/Transforms/Utils/SSAUpdater.cpp | ||
---|---|---|
221 | This patch doesnt introduce any newly created undef Values, just moving where they're created, so I believe it should stay undef for now, until this and the relevant tests are migrated |
llvm/include/llvm/Transforms/Utils/SSAUpdater.h | ||
---|---|---|
121 |
Please generate diffs with full context (e.g., -U999999 in the diff/show command). It's really helpful to be able to look above and below the modified lines to understand the context of the patch.
One minor comment. I don't feel comfortable enough with metadata to actually approve this, however.
llvm/lib/Transforms/Scalar/JumpThreading.cpp | ||
---|---|---|
2058 |
FYI, it looks like this broke https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/50434/testReport/junit/lldb-api/tools_lldb-vscode_optimized/TestVSCode_optimized_py/ where we're presumably relying on a variable to have gotten optimised out but which is now not the case anymore. So not an issue with this patch necessarily, just notifying.
Snippet from test:
int main(int argc, char const *argv[]) { int optimized = argc > 1 ? std::stoi(argv[1]) : 0; printf("argc: %d, optimized: %d\n", argc, optimized);
compiled with -glldb -O3
If it's relying on debug info to get lost would using a nodebug attribute work, or does it need a variable, but without a location? In that case, we could rewrite the test to compile to LLVM IR at -O0, use sed to remote the location from the dbg.declare() and then compile the patch IR with clang. That would be cross-architecture and slightly more reliable (if still ugly) than relying on -O3 doing something specific.
Hi,
It looks like this patch makes jump-threading yield different results with/without debug info.
With
opt -passes=jump-threading bbi-78731_red.ll -S -o -
We get e.g
for.cond: ; preds = %lor.end51, %entry %cond4130 = phi i32 [ undef, %entry ], [ %cond4131, %lor.end51 ] %e.0 = phi i32 [ 0, %entry ], [ %cond3111226, %lor.end51 ]
and if we comment out the call to llvm.dbg.value we instead get
for.cond: ; preds = %lor.end51, %entry %e.0 = phi i32 [ 0, %entry ], [ %cond3111226, %lor.end51 ]
/me squints -- I think the idea here was that if SSAUpdater has a value at the end of the block we can use that and it won't cause new codegen; but then we're using GetValueInMiddleOfBlock, which will generate code in certain circumstances.
@StephenTozer @BenJMudd Presumably we can just use GetValueAtEndOfBlock as this isn't a general SSA update query, we have a guarantee that only blocks outside of the the (threaded) value definitions will be updated, where there's no need to consider definitions in the middle of the block.
I just did a quick test to do
void SSAUpdater::UpdateDebugValue(Instruction *I, DbgValueInst *DbgValue) { BasicBlock *UserBB = DbgValue->getParent(); if (HasValueForBlock(UserBB)) { - Value *NewVal = GetValueInMiddleOfBlock(UserBB); + Value *NewVal = GetValueAtEndOfBlock(UserBB); DbgValue->replaceVariableLocationOp(I, NewVal); } else DbgValue->setKillLocation(); }
and then the difference I saw with/without debug info disappears.
I don't know anything about this, just wanted to let you know your suggestion indeed seems to work.
Ah, my bad - I've bumped into this before and saw the potential for CodeGen changes, but misread/misremembered the logic and thought that the HasValueForBlock check was guarding against CodeGen. I think GetValueAtEndOfBlock can also generate SSA, the function for this is FindValueForBlock.
Ah ok, I had no idea that GetValueInMiddleOfBlock was causing code gen. @StephenTozer using FindValueForBlock seems to be the best solution then, thanks.
Actually looking back over it I'd add further - FindValueForBlock isn't necessarily right because we're looking for values in the middle of the block, and that function will give us the value at the end only (which may be incorrect depending on the position of the debug value). I encountered this problem in MachineSSAUpdater, and the approach I took there was to add a ExistingValueOnly parameter to GetValue(InMiddle|AtEnd)OfBlock that performs all the same logic but returns empty if it would need to generate any code to provide a value. Happy to repeat that fix here!
Cool, sounds like this is just a case of mistaken-function-identity, thanks for catching this @uabelho. I'll drop in a follow-up patch shortly to use GetValueAtEndOfBlock