-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JumpThreading miscompilation in presence of @​llvm.assume due to DomTree not being updated *between* iterations #35481
Comments
assigned to @bmrzycki |
With the following LLVM IR: @global = external local_unnamed_addr global i8*, align 8 define i32 @foo(i32 %arg) local_unnamed_addr #0 { bb2: bb3: bb6: bb7: bb9: ; Single pred - %bb7 bb10: ; Single pred - %bb7 ; Function Attrs: nounwind attributes #0 = { uwtable } Running opt -jump-threading -S < a.ll I got ; Function Attrs: uwtable bb7: bb9: bb10: ; Function Attrs: nounwind attributes #0 = { uwtable } I've tracked it down to JumpThreading and LVI interaction when LVI checks if the call to @llvm.assume dominates the condition that JT asks for. However, due to stale DomTree info the answer turns out to be wrong. Changing JumpThreading like this:
Fixes the miscompilation but is going to affect compile time a lot (as noted in https://reviews.llvm.org/D34135#979097) |
Hello Andrei, thank you for reducing this problem down. I agree with your assessment that the proposed patch here will negatively impact performance. It would be best to trace down ProcessBlock() to determine exactly which LVI check is being incorrectly calculated. I will start GDB tracing this to determine if I can find it |
I'm not sure I fully understand what you mean, but maybe this will help: // In ValueTracking.cpp: if (DT) { which was called from for (auto &AssumeVH : AC->assumptionsFor(Val)) {
} |
Hi Andrei, I appreciate the function listings to examine, they will help. I don't think this problem is caused by the DDT patch. On my Ubuntu 16.04 host In my testing this problem still occurs in a release version of LLVM 5.0 installed as a debian package. Here are the release compiler versions used for testing: Here is the llvm-project tip SHA used for tip:
I am attaching all the files I used to test for you to verify their contents. I had to create two different input.ll files due to changes to the IR format between 3.8 and 5.0. When I tried to compile the 5.0 IR with 3.8 I received errors about source_filename and the local_unnamed_addr attribute. Here's how I generated the JumpThreaded output IR: The diff of tip and 5.0 is identical: The diff of 5.0 and 3.8 is not: -@global = external local_unnamed_addr global i8*, align 8 ; Function Attrs: uwtable
-bb7: ; preds = %bb bb9: ; preds = %bb7 -bb10: ; preds = %bb, %bb7 |
LLVM tip (SHA 3c7922ee800de037147f3a2f801c410815043f07) JumpThreading |
LLVM 5.0 JumpThreading |
LLVM 3.8 JumpThreading |
I never wanted to say that, sorry if that was not clear. The reason I included you (and mentioned D34135) is because DDT supposes that DomTree information is only updated after the pass which is not the case neither for unreachable BBs created by JT nor for this defect. My impression was the direction of the discussion related to dead BBs is to workaround it somehow without proper update of DomTree between iterations. I though that another test case that has the same root cause but does not involve unreachable BBs might be useful to consider. |
I am still looking into this bug to see if I can add any more insights. |
Through bisection I believe I have found the commit causing the problem: commit 5f9df53
And here is the immediately preceding commit: commit a2f4a537f655fd9f543dd462049f47e6c1dfba99
( The SHAs come from the unified git repo https://github.com/llvm-project/llvm-project-20170507.git ) Here is the output of the commit just before commit a2f4a537f655fd9f543dd462049f47e6c1dfba99
The analysis: $ /work/brzycki/bisect_817f15e61e475cd04122/build/bin/opt -S -jump-threading input38.ll >good.ll @global = external global i8*, align 8 $ /work/brzycki/bisect_5f9df53e57e8e81d42cf/build/bin/opt -S -jump-threading input38.ll > bad.ll @global = external global i8*, align 8 @@ -7,16 +8,16 @@
-bb7: ; preds = %bb, %bb bb9: ; preds = %bb7 -bb10: ; preds = %bb7 |
Correction, here are the correct SHAs from (https://github.com/llvm-project/llvm-project-20170507.git): commit 5f9df53
Notes: commit 817f15e
Notes: |
Here is the problem written in c code. It's easier to see the problem: #define true 1 extern char *global; /* ORIGINAL */ /* CORRECT: The state of global does not alter the control flow. */ /* INCORRECT: The state of global must not alter the control flow. */ The JumpThreaded 5.0+ version incorrectly threads a jump from bb to bb10 in the case global tmp pointer is null. |
There are two things going on here. The first is that the commit I mentioned causes the problem. The second is that the problem manifests differently with LLVM tip. I was incorrect. In the case of tip there does exist a problem between DDT, JumpThreading, and LVI. In JumpThreading we have the following code: // Get DT analysis before LVI. When LVI is initialized it conditionally adds What happens here is LVI is initialized with its own local handle to the global DominatorTree structure. This means any time we use LVI for analysis, and that analysis relies on its DT, and JT has pending updates to the DT inside of DDT we have the potential for incorrect analysis. In this test case JT begins analysis of bb7 and enters ComputeValueKnownInPredecessors(). The dependant value V is "icmp sgt i32 %arg, -1". In that function we eventually get to the following code:
The underlying implementation of getPredicateOnEdge() uses DT to determine if "%arg" is an integer and incorrectly says it is. This causes JumpThreading to thread across bb7 into bb10 from bb3, bypassing the mandatory check of (arg == -1). The fix requires flushing the DDT whenever LVI analysis is required. I will post a patch to Phabricator shortly. |
Fix pushed to |
mentioned in issue llvm/llvm-bugzilla-archive#36386 |
The text was updated successfully, but these errors were encountered: