[llvm] [SpeculativeExecution] Drop poison-generating flags when hoisting instructions (PR #225377)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 22 04:52:43 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Adrian Kuegel (akuegel)
<details>
<summary>Changes</summary>
When SpeculativeExecutionPass::considerHoistingFromTo hoists instructions out of a conditionally executed basic block into a dominating block, any poison-generating flags (such as `disjoint`, `nsw`, `nuw`, `exact`, or `inbounds`) that were inferred under the branch condition may no longer hold in the dominating block.
For example, `InstCombine` can fold `add i32 %x, -2` to `or disjoint i32 %x, -2` inside an `if (%x < 2)` block. If `SpeculativeExecutionPass` hoists the `or disjoint` above `if (%x < 2)` without dropping `disjoint`, subsequent passes such as `NaryReassociate` (via `ScalarEvolution`) or `EarlyCSE` treat the hoisted `or disjoint %x, -2` as equivalent to `add %x, -2` in other blocks where `%x >= 2`, causing a miscompilation.
Call `dropPoisonGeneratingFlags()` on hoisted instructions.
Assisted-by: Gemini
---
Full diff: https://github.com/llvm/llvm-project/pull/225377.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp (+1)
- (modified) llvm/test/Transforms/SpeculativeExecution/spec.ll (+20)
``````````diff
diff --git a/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp b/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp
index 0a2a3f8a495bf..2dcabaf7644fa 100644
--- a/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp
+++ b/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp
@@ -320,6 +320,7 @@ bool SpeculativeExecutionPass::considerHoistingFromTo(
if (!NotHoisted.count(&*Current)) {
Current->moveBefore(ToBlock.getTerminator()->getIterator());
Current->dropLocation();
+ Current->dropPoisonGeneratingFlags();
}
}
return true;
diff --git a/llvm/test/Transforms/SpeculativeExecution/spec.ll b/llvm/test/Transforms/SpeculativeExecution/spec.ll
index 9f409eb059f43..95c6306f04b5a 100644
--- a/llvm/test/Transforms/SpeculativeExecution/spec.ll
+++ b/llvm/test/Transforms/SpeculativeExecution/spec.ll
@@ -193,3 +193,23 @@ a:
b:
ret void
}
+
+; Drop poison-generating flags when hoisting.
+define void @dropPoisonFlags(i32 %val, ptr %p) {
+; CHECK-LABEL: @dropPoisonFlags(
+; CHECK-NEXT: %or = or i32 %val, -2{{$}}
+; CHECK-NEXT: %add = add i32 %or, 1{{$}}
+; CHECK-NEXT: %gep = getelementptr i8, ptr %p, i32 %add{{$}}
+; CHECK-NEXT: br i1 true
+ br i1 true, label %a, label %b
+; CHECK: a:
+a:
+ %or = or disjoint i32 %val, -2
+ %add = add nuw nsw i32 %or, 1
+ %gep = getelementptr inbounds i8, ptr %p, i32 %add
+ br label %b
+; CHECK: b:
+b:
+ ret void
+}
+
``````````
</details>
https://github.com/llvm/llvm-project/pull/225377
More information about the llvm-commits
mailing list