[PATCH] D153698: [InstCombine] canonicalize multi xor as cmp+select

Allen zhong via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Jun 24 04:06:02 PDT 2023


Allen created this revision.
Allen added reviewers: nikic, RKSimon, dmgreen, k-arrows, junaire, 0xdc03.
Herald added subscribers: StephenFan, hiraditya.
Herald added a project: All.
Allen requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

extend simplifyWithOpReplaced to look at more than one instruction for Xor instruction.

https://github.com/llvm/llvm-project/issues/63104


https://reviews.llvm.org/D153698

Files:
  llvm/lib/Analysis/InstructionSimplify.cpp
  llvm/test/Transforms/InstCombine/select-cmp.ll


Index: llvm/test/Transforms/InstCombine/select-cmp.ll
===================================================================
--- llvm/test/Transforms/InstCombine/select-cmp.ll
+++ llvm/test/Transforms/InstCombine/select-cmp.ll
@@ -345,4 +345,18 @@
   ret i1 %r
 }
 
+; https://alive2.llvm.org/ce/z/TGgJTq
+define i32 @select_icmp_xor_multi_insn(i32 noundef %a, i32 noundef %b) {
+; CHECK-LABEL: @select_icmp_xor_multi_insn(
+; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[TMP1]], -1
+; CHECK-NEXT:    ret i32 [[XOR1]]
+;
+  %tobool = icmp eq i32 %a, %b
+  %not = xor i32 %a, -1
+  %xor1 = xor i32 %not, %b
+  %cond = select i1 %tobool, i32 -1, i32 %xor1
+  ret i32 %cond
+}
+
 declare void @use(i1)
Index: llvm/lib/Analysis/InstructionSimplify.cpp
===================================================================
--- llvm/lib/Analysis/InstructionSimplify.cpp
+++ llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4253,11 +4253,21 @@
     return RepOp;
 
   // We cannot replace a constant, and shouldn't even try.
-  if (isa<Constant>(Op))
+  if (isa<Constant>(Op) || !isa<Instruction>(V))
     return nullptr;
 
-  auto *I = dyn_cast<Instruction>(V);
-  if (!I || !is_contained(I->operands(), Op))
+  auto *I = cast<Instruction>(V);
+  if (I->getOpcode() == Instruction::Xor && !is_contained(I->operands(), Op)) {
+    Value *S = simplifyWithOpReplaced(I->getOperand(0), Op, RepOp, Q,
+                                      AllowRefinement, MaxRecurse);
+    if (!S)
+      return nullptr;
+    Constant *Cst = dyn_cast<Constant>(S);
+    if (Cst && Cst->isNullValue())
+      return I->getOperand(1);
+  }
+
+  if (!is_contained(I->operands(), Op))
     return nullptr;
 
   // The arguments of a phi node might refer to a value from a previous


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D153698.534191.patch
Type: text/x-patch
Size: 1800 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230624/bd8b844b/attachment.bin>


More information about the llvm-commits mailing list