[llvm] acafde0 - [InstCombine] enhance icmp with sub folds
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Sat Oct 9 09:20:45 PDT 2021
Author: Sanjay Patel
Date: 2021-10-09T11:39:49-04:00
New Revision: acafde09a3fa9560148605f35f9c3d3f1444bc15
URL: https://github.com/llvm/llvm-project/commit/acafde09a3fa9560148605f35f9c3d3f1444bc15
DIFF: https://github.com/llvm/llvm-project/commit/acafde09a3fa9560148605f35f9c3d3f1444bc15.diff
LOG: [InstCombine] enhance icmp with sub folds
There were 2 related but over-specified folds for:
C1 - X == C
One allowed multi-use but was limited to equal constants.
The other allowed different constants but disallowed multi-use.
This combines the 2 folds into a more general match.
The test diffs show the multi-use cases that were falling
through the cracks.
https://alive2.llvm.org/ce/z/4_hEt2
define i1 @src(i8 %x, i8 %subC, i8 %C) {
%s = sub i8 %subC, %x
%r = icmp eq i8 %s, %C
ret i1 %r
}
define i1 @tgt(i8 %x, i8 %subC, i8 %C) {
%newC = sub i8 %subC, %C
%isneg = icmp eq i8 %x, %newC
ret i1 %isneg
}
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/icmp-sub.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 03044acd716d1..e080e7f95168e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -2579,21 +2579,25 @@ Instruction *InstCombinerImpl::foldICmpSubConstant(ICmpInst &Cmp,
const APInt &C) {
Value *X = Sub->getOperand(0), *Y = Sub->getOperand(1);
ICmpInst::Predicate Pred = Cmp.getPredicate();
- const APInt *C2;
- APInt SubResult;
+ Type *Ty = Sub->getType();
- // icmp eq/ne (sub C, Y), C -> icmp eq/ne Y, 0
- if (match(X, m_APInt(C2)) && *C2 == C && Cmp.isEquality())
- return new ICmpInst(Cmp.getPredicate(), Y,
- ConstantInt::get(Y->getType(), 0));
+ // (SubC - Y) == C) --> Y == (SubC - C)
+ // (SubC - Y) != C) --> Y != (SubC - C)
+ Constant *SubC;
+ if (Cmp.isEquality() && match(X, m_ImmConstant(SubC))) {
+ return new ICmpInst(Pred, Y,
+ ConstantExpr::getSub(SubC, ConstantInt::get(Ty, C)));
+ }
// (icmp P (sub nuw|nsw C2, Y), C) -> (icmp swap(P) Y, C2-C)
+ const APInt *C2;
+ APInt SubResult;
if (match(X, m_APInt(C2)) &&
((Cmp.isUnsigned() && Sub->hasNoUnsignedWrap()) ||
(Cmp.isSigned() && Sub->hasNoSignedWrap())) &&
!subWithOverflow(SubResult, *C2, C, Cmp.isSigned()))
return new ICmpInst(Cmp.getSwappedPredicate(), Y,
- ConstantInt::get(Y->getType(), SubResult));
+ ConstantInt::get(Ty, SubResult));
// The following transforms are only worth it if the only user of the subtract
// is the icmp.
@@ -3122,12 +3126,7 @@ Instruction *InstCombinerImpl::foldICmpBinOpEqualityWithConstant(
break;
case Instruction::Sub:
if (BO->hasOneUse()) {
- // Only check for constant LHS here, as constant RHS will be canonicalized
- // to add and use the fold above.
- if (Constant *BOC = dyn_cast<Constant>(BOp0)) {
- // Replace ((sub BOC, B) != C) with (B != BOC-C).
- return new ICmpInst(Pred, BOp1, ConstantExpr::getSub(BOC, RHS));
- } else if (C.isZero()) {
+ if (C.isZero()) {
// Replace ((sub A, B) != 0) with (A != B).
return new ICmpInst(Pred, BOp0, BOp1);
}
diff --git a/llvm/test/Transforms/InstCombine/icmp-sub.ll b/llvm/test/Transforms/InstCombine/icmp-sub.ll
index 4fa31bee61f17..0b62df6042585 100644
--- a/llvm/test/Transforms/InstCombine/icmp-sub.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-sub.ll
@@ -204,7 +204,7 @@ define i1 @neg_eq_43(i32 %x) {
; CHECK-LABEL: @neg_eq_43(
; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X:%.*]]
; CHECK-NEXT: call void @use(i32 [[NEGX]])
-; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[NEGX]], 43
+; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X]], -43
; CHECK-NEXT: ret i1 [[R]]
;
%negx = sub i32 0, %x
@@ -217,7 +217,7 @@ define i1 @neg_ne_44(i32 %x) {
; CHECK-LABEL: @neg_ne_44(
; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X:%.*]]
; CHECK-NEXT: call void @use(i32 [[NEGX]])
-; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[NEGX]], 44
+; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[X]], -44
; CHECK-NEXT: ret i1 [[R]]
;
%negx = sub i32 0, %x
@@ -230,7 +230,7 @@ define i1 @neg_nsw_eq_45(i32 %x) {
; CHECK-LABEL: @neg_nsw_eq_45(
; CHECK-NEXT: [[NEGX:%.*]] = sub nsw i32 0, [[X:%.*]]
; CHECK-NEXT: call void @use(i32 [[NEGX]])
-; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[NEGX]], 45
+; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X]], -45
; CHECK-NEXT: ret i1 [[R]]
;
%negx = sub nsw i32 0, %x
@@ -243,7 +243,7 @@ define i1 @neg_nsw_ne_46(i32 %x) {
; CHECK-LABEL: @neg_nsw_ne_46(
; CHECK-NEXT: [[NEGX:%.*]] = sub nsw i32 0, [[X:%.*]]
; CHECK-NEXT: call void @use(i32 [[NEGX]])
-; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[NEGX]], 46
+; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[X]], -46
; CHECK-NEXT: ret i1 [[R]]
;
%negx = sub nsw i32 0, %x
@@ -256,7 +256,7 @@ define i1 @subC_eq(i32 %x) {
; CHECK-LABEL: @subC_eq(
; CHECK-NEXT: [[SUBX:%.*]] = sub i32 -2147483648, [[X:%.*]]
; CHECK-NEXT: call void @use(i32 [[SUBX]])
-; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[SUBX]], 43
+; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X]], 2147483605
; CHECK-NEXT: ret i1 [[R]]
;
%subx = sub i32 -2147483648, %x
@@ -269,7 +269,7 @@ define <2 x i1> @subC_ne(<2 x i8> %x) {
; CHECK-LABEL: @subC_ne(
; CHECK-NEXT: [[SUBX:%.*]] = sub <2 x i8> <i8 -6, i8 -128>, [[X:%.*]]
; CHECK-NEXT: call void @use_vec(<2 x i8> [[SUBX]])
-; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[SUBX]], <i8 -44, i8 -44>
+; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[X]], <i8 38, i8 -84>
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%subx = sub <2 x i8> <i8 -6, i8 -128>, %x
@@ -282,7 +282,7 @@ define i1 @subC_nsw_eq(i32 %x) {
; CHECK-LABEL: @subC_nsw_eq(
; CHECK-NEXT: [[SUBX:%.*]] = sub nsw i32 -100, [[X:%.*]]
; CHECK-NEXT: call void @use(i32 [[SUBX]])
-; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[SUBX]], -2147483648
+; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X]], 2147483548
; CHECK-NEXT: ret i1 [[R]]
;
%subx = sub nsw i32 -100, %x
@@ -295,7 +295,7 @@ define i1 @subC_nsw_ne(i32 %x) {
; CHECK-LABEL: @subC_nsw_ne(
; CHECK-NEXT: [[SUBX:%.*]] = sub nsw i32 -2147483647, [[X:%.*]]
; CHECK-NEXT: call void @use(i32 [[SUBX]])
-; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[SUBX]], 46
+; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[X]], 2147483603
; CHECK-NEXT: ret i1 [[R]]
;
%subx = sub nsw i32 -2147483647, %x
More information about the llvm-commits
mailing list