[llvm] [InstCombine] Fix run twice at once (#77553) (PR #77738)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 10 23:47:12 PST 2024


https://github.com/ParkHanbum created https://github.com/llvm/llvm-project/pull/77738

`InstCombine` uses `Worklist` to manage change history. `setOperand`, which was previously used to change the `Select` Instruction, does not, so it is `run` twice, which causes an `LLVM ERROR`.

This problem is resolved by changing `setOperand` to `replaceOperand` as the change history will be registered in the Worklist.

>From 1101d9971ea78ac790b3152dab165ac670d22a3e Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Thu, 11 Jan 2024 16:29:40 +0900
Subject: [PATCH] [InstCombine] Fix run twice at once (#77553)

`InstCombine` uses `Worklist` to manage change history. `setOperand`,
which was previously used to change the `Select` Instruction, does not,
so it is `run` twice, which causes an `LLVM ERROR`.

This problem is resolved by changing `setOperand` to `replaceOperand`
as the change history will be registered in the Worklist.
---
 .../Transforms/InstCombine/InstCombineSelect.cpp   |  4 ++--
 llvm/test/Transforms/InstCombine/select.ll         | 14 ++++++++++++++
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 2dda46986f0fd0..1aa47b2ccfd82b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -1703,11 +1703,11 @@ Instruction *InstCombinerImpl::foldSelectInstWithICmp(SelectInst &SI,
   if (CmpRHS != CmpLHS && isa<Constant>(CmpRHS) && !isa<Constant>(CmpLHS)) {
     if (CmpLHS == TrueVal && Pred == ICmpInst::ICMP_EQ) {
       // Transform (X == C) ? X : Y -> (X == C) ? C : Y
-      SI.setOperand(1, CmpRHS);
+      replaceOperand(SI, 1, CmpRHS);
       Changed = true;
     } else if (CmpLHS == FalseVal && Pred == ICmpInst::ICMP_NE) {
       // Transform (X != C) ? Y : X -> (X != C) ? Y : C
-      SI.setOperand(2, CmpRHS);
+      replaceOperand(SI, 2, CmpRHS);
       Changed = true;
     }
   }
diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index 7583a75385a769..5687371b4e1dd2 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -3646,3 +3646,17 @@ loop:
 exit:
   ret i32 %rem
 }
+
+; (X == C) ? X : Y -> (X == C) ? C : Y
+; Fixed #77553
+define i32 @src_select_xxory_eq0_xorxy_y(i32 %x, i32 %y) {
+; CHECK-LABEL: @src_select_xxory_eq0_xorxy_y(
+; CHECK-NEXT:    [[XOR0:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[COND:%.*]] = select i1 [[XOR0]], i32 0, i32 [[Y]]
+; CHECK-NEXT:    ret i32 [[COND]]
+;
+  %xor = xor i32 %x, %y
+  %xor0 = icmp eq i32 %xor, 0
+  %cond = select i1 %xor0, i32 %xor, i32 %y
+  ret i32 %cond
+}



More information about the llvm-commits mailing list