[llvm] [EarlyCSE] Fix improper icmp simplification (PR #122043)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 7 18:49:11 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-analysis

Author: None (llvmssh)

<details>
<summary>Changes</summary>

When icmp's argument is a volatile instruction, we do not assume that icmp can be simplified.

---
Full diff: https://github.com/llvm/llvm-project/pull/122043.diff


2 Files Affected:

- (modified) llvm/lib/Analysis/InstructionSimplify.cpp (+15) 
- (added) llvm/test/Transforms/EarlyCSE/icmp_with_volatile.ll (+40) 


``````````diff
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 515806428cbb29..db5156fcab9c1a 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -3726,6 +3726,21 @@ static Value *simplifyICmpInst(CmpPredicate Pred, Value *LHS, Value *RHS,
                                const SimplifyQuery &Q, unsigned MaxRecurse) {
   assert(CmpInst::isIntPredicate(Pred) && "Not an integer compare!");
 
+  // volatile check
+  // %mark = load volatile ptr, ptr %1, align 8
+  // icmp eq ptr %mark, null
+  if (const auto LHSInstr = dyn_cast<Instruction>(LHS)) {
+     if (LHSInstr->isVolatile()) {
+       return nullptr;
+     }
+  }
+
+  if (const auto RHSInstr = dyn_cast<Instruction>(RHS)) { 
+     if (RHSInstr->isVolatile()) {
+        return nullptr;
+     }
+  }
+
   if (Constant *CLHS = dyn_cast<Constant>(LHS)) {
     if (Constant *CRHS = dyn_cast<Constant>(RHS))
       return ConstantFoldCompareInstOperands(Pred, CLHS, CRHS, Q.DL, Q.TLI);
diff --git a/llvm/test/Transforms/EarlyCSE/icmp_with_volatile.ll b/llvm/test/Transforms/EarlyCSE/icmp_with_volatile.ll
new file mode 100644
index 00000000000000..d85d56d50fb4a6
--- /dev/null
+++ b/llvm/test/Transforms/EarlyCSE/icmp_with_volatile.ll
@@ -0,0 +1,40 @@
+; RUN: opt < %s -S -passes=early-cse | FileCheck %s
+
+;When icmp's argument is a volatile instruction, we do not assume that icmp can
+;be simplified.
+define dso_local noundef i32 @_Z1funcv() {
+; CHECK-LABEL: @_Z1funcv(
+; CHECK-NEXT:    %1 = alloca ptr, align 8
+; CHECK-NEXT:    store volatile ptr null, ptr %1, align 8
+; CHECK-NEXT:    %2 = load volatile ptr, ptr %1, align 8
+; CHECK-NEXT:    %3 = ptrtoint ptr %2 to i64
+; CHECK-NEXT:    %4 = and i64 %3, 1
+; CHECK-NEXT:    %5 = icmp eq i64 %4, 0
+; CHECK-NEXT:    %6 = zext i1 %5 to i32
+; CHECK-NEXT:    ret i32 %6
+;
+  %1 = alloca ptr, align 8
+  store volatile ptr null, ptr %1, align 8
+  %2 = load volatile ptr, ptr %1, align 8
+  %3 = ptrtoint ptr %2 to i64
+  %4 = and i64 %3, 1
+  %5 = icmp eq i64 %4, 0
+  %6 = zext i1 %5 to i32
+  ret i32 %6
+}
+
+define dso_local noundef i32 @_Z2funcv() {
+; CHECK-LABEL: @_Z2funcv(
+; CHECK-NEXT:    %1 = alloca ptr, align 8
+; CHECK-NEXT:    store ptr null, ptr %1, align 8
+; CHECK-NEXT:    ret i32 1
+;
+  %1 = alloca ptr, align 8
+  store ptr null, ptr %1, align 8
+  %2 = load ptr, ptr %1, align 8
+  %3 = ptrtoint ptr %2 to i64
+  %4 = and i64 %3, 1
+  %5 = icmp eq i64 %4, 0
+  %6 = zext i1 %5 to i32
+  ret i32 %6
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/122043


More information about the llvm-commits mailing list