[PATCH] D108408: [InstSimplify] Transform X == 0 ? 0 : X * Y --> X * freeze(Y).

Filipp Zhinkin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 19 14:08:48 PDT 2021


fzhinkin created this revision.
Herald added a subscriber: hiraditya.
fzhinkin requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Enabled folding optimization that was previously disabled by being incorrect.
To preserve correctness mul's operand that is not compared with zero in select's condition is now frozen.

Related bug: https://bugs.llvm.org/show_bug.cgi?id=51286

Correctness:
https://alive2.llvm.org/ce/z/bHef7J
https://alive2.llvm.org/ce/z/QcR7sf


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D108408

Files:
  llvm/lib/Analysis/InstructionSimplify.cpp
  llvm/test/Transforms/InstSimplify/select.ll


Index: llvm/test/Transforms/InstSimplify/select.ll
===================================================================
--- llvm/test/Transforms/InstSimplify/select.ll
+++ llvm/test/Transforms/InstSimplify/select.ll
@@ -1066,3 +1066,27 @@
   %v = select <2 x i1> %cond, <2 x i32> %x, <2 x i32> poison
   ret <2 x i32> %v
 }
+
+define i32 @mul_by_zero(i32 %x, i32 %y) {
+; CHECK-LABEL: @mul_by_zero(
+; CHECK-NEXT:    [[Y_FROZEN:%.*]] = freeze i32 [[Y:%.*]]
+; CHECK-NEXT:    [[M:%.*]] = mul i32 [[X:%.*]], [[Y_FROZEN]]
+; CHECK-NEXT:    ret i32 [[M]]
+;
+  %c = icmp eq i32 %x, 0
+  %m = mul i32 %x, %y
+  %r = select i1 %c, i32 0, i32 %m
+  ret i32 %r
+}
+
+define i32 @mul_by_zero1(i32 %x, i32 %y) {
+; CHECK-LABEL: @mul_by_zero1(
+; CHECK-NEXT:    [[X_FROZEN:%.*]] = freeze i32 [[X:%.*]]
+; CHECK-NEXT:    [[M:%.*]] = mul i32 [[X_FROZEN]], [[Y:%.*]]
+; CHECK-NEXT:    ret i32 [[M]]
+;
+  %c = icmp eq i32 %y, 0
+  %m = mul i32 %x, %y
+  %r = select i1 %c, i32 0, i32 %m
+  ret i32 %r
+}
Index: llvm/lib/Analysis/InstructionSimplify.cpp
===================================================================
--- llvm/lib/Analysis/InstructionSimplify.cpp
+++ llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4136,6 +4136,21 @@
               m_Neg(m_Intrinsic<Intrinsic::abs>(m_Specific(CmpLHS)))) &&
         match(FalseVal, m_Intrinsic<Intrinsic::abs>(m_Specific(CmpLHS))))
       return FalseVal;
+
+    // X == 0 ? 0 : X * X2 --> X * freeze(X2)
+    // X2 == 0 ? 0 : X * X2 --> freeze(X) * X2
+    Value *X2;
+    if (match(TrueVal, m_Zero()) &&
+        match(FalseVal, m_Mul(m_Value(X), m_Value(X2)))) {
+      unsigned OperandIndex = 0;
+      if (X == CmpLHS) {
+        X = X2;
+        OperandIndex = 1;
+      }
+      auto *I = cast<Instruction>(FalseVal);
+      I->setOperand(OperandIndex, new FreezeInst(X, X->getName() + ".fr", I));
+      return FalseVal;
+    }
   }
 
   // Check for other compares that behave like bit test.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D108408.367609.patch
Type: text/x-patch
Size: 1939 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210819/1cb284ed/attachment.bin>


More information about the llvm-commits mailing list