[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