[PATCH] D144777: [InstCombine] Fold signbit test of a pow2 or zero
Jun Zhang via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sun Feb 26 06:15:11 PST 2023
junaire updated this revision to Diff 500560.
junaire added a comment.
Address comments, thanks @RKSimon
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D144777/new/
https://reviews.llvm.org/D144777
Files:
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/fold-signbit-test-power2.ll
llvm/test/Transforms/InstCombine/minmax-of-xor-x.ll
Index: llvm/test/Transforms/InstCombine/minmax-of-xor-x.ll
===================================================================
--- llvm/test/Transforms/InstCombine/minmax-of-xor-x.ll
+++ llvm/test/Transforms/InstCombine/minmax-of-xor-x.ll
@@ -134,9 +134,7 @@
define i8 @smax_xor_pow2_neg(i8 %x, i8 %y) {
; CHECK-LABEL: @smax_xor_pow2_neg(
-; CHECK-NEXT: [[NY:%.*]] = sub i8 0, [[Y:%.*]]
-; CHECK-NEXT: [[YP2:%.*]] = and i8 [[NY]], [[Y]]
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[YP2]], 0
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[Y:%.*]], -128
; CHECK-NEXT: br i1 [[CMP]], label [[NEG:%.*]], label [[POS:%.*]]
; CHECK: neg:
; CHECK-NEXT: [[R:%.*]] = and i8 [[X:%.*]], 127
Index: llvm/test/Transforms/InstCombine/fold-signbit-test-power2.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/InstCombine/fold-signbit-test-power2.ll
@@ -0,0 +1,45 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+define i1 @pow2_or_zero1(i8 %x) {
+; CHECK-LABEL: @pow2_or_zero1(
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], -128
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %negx = sub i8 0, %x
+ %pow2_or_zero = and i8 %negx, %x
+ %cmp = icmp slt i8 %pow2_or_zero, 0
+ ret i1 %cmp
+}
+
+define i1 @pow2_or_zero2(i8 %x) {
+; CHECK-LABEL: @pow2_or_zero2(
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], -128
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %negx = sub i8 0, %x
+ %pow2_or_zero = and i8 %x, %negx
+ %cmp = icmp slt i8 %pow2_or_zero, 0
+ ret i1 %cmp
+}
+
+define i1 @pow2_or_zero3(i8 %x) {
+; CHECK-LABEL: @pow2_or_zero3(
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[X:%.*]], -128
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %negx = sub i8 0, %x
+ %pow2_or_zero = and i8 %negx, %x
+ %cmp = icmp sgt i8 %pow2_or_zero, -1
+ ret i1 %cmp
+}
+
+define i1 @pow2_or_zero4(i8 %x) {
+; CHECK-LABEL: @pow2_or_zero4(
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[X:%.*]], -128
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %negx = sub i8 0, %x
+ %pow2_or_zero = and i8 %x, %negx
+ %cmp = icmp sgt i8 %pow2_or_zero, -1
+ ret i1 %cmp
+}
Index: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -1337,6 +1337,19 @@
if (Instruction *Res = processUGT_ADDCST_ADD(Cmp, A, B, CI2, CI, *this))
return Res;
+ Value *X;
+ // icmp slt (and -X, X), 0 --> icmp eq (X, CI)
+ // icmp sgt (and -X, X), -1 --> icmp ne (X, CI)
+ if (match(Op0, m_OneUse(m_c_And(m_Neg(m_Value(X)), m_Deferred(X))))) {
+ Constant *CI = ConstantInt::get(
+ X->getType(),
+ APInt::getSignedMinValue(X->getType()->getScalarSizeInBits()));
+ if (Pred == ICmpInst::ICMP_SLT && match(Op1, m_Zero()))
+ return new ICmpInst(ICmpInst::ICMP_EQ, X, CI);
+ if (Pred == ICmpInst::ICMP_SGT && match(Op1, m_AllOnes()))
+ return new ICmpInst(ICmpInst::ICMP_NE, X, CI);
+ }
+
// icmp(phi(C1, C2, ...), C) -> phi(icmp(C1, C), icmp(C2, C), ...).
Constant *C = dyn_cast<Constant>(Op1);
if (!C)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D144777.500560.patch
Type: text/x-patch
Size: 3249 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230226/d9d86c7d/attachment.bin>
More information about the llvm-commits
mailing list