[llvm] ca6e117 - [InstCombine] reorder icmp with offset folds for better results
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 14 09:12:14 PDT 2021
Author: Sanjay Patel
Date: 2021-07-14T12:12:05-04:00
New Revision: ca6e117d86341682e20025f204294c0ca78c355e
URL: https://github.com/llvm/llvm-project/commit/ca6e117d86341682e20025f204294c0ca78c355e
DIFF: https://github.com/llvm/llvm-project/commit/ca6e117d86341682e20025f204294c0ca78c355e.diff
LOG: [InstCombine] reorder icmp with offset folds for better results
This set of folds was added recently with:
c7b658aeb526
0c400e895306
40b752d28d95
...and I noted that this wasn't likely to fire in code derived
from C/C++ source because of nsw in particular. But I didn't
notice that I had placed the code above the no-wrap block
of transforms.
This is likely the cause of regressions noted from the previous
commit because -- as shown in the test diffs -- we may have
transformed into a compare with an arbitrary constant rather
than a simpler signbit test.
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/icmp-add.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 031b95e9c087..6de4c4d4aa34 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -2650,25 +2650,6 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
Value *X = Add->getOperand(0);
Type *Ty = Add->getType();
const CmpInst::Predicate Pred = Cmp.getPredicate();
- const APInt SMax = APInt::getSignedMaxValue(Ty->getScalarSizeInBits());
- const APInt SMin = APInt::getSignedMinValue(Ty->getScalarSizeInBits());
-
- // Fold compare with offset to opposite sign compare if it eliminates offset:
- // (X + C2) >u C --> X <s -C2 (if C == C2 + SMAX)
- if (Pred == CmpInst::ICMP_UGT && C == *C2 + SMax)
- return new ICmpInst(ICmpInst::ICMP_SLT, X, ConstantInt::get(Ty, -(*C2)));
-
- // (X + C2) <u C --> X >s ~C2 (if C == C2 + SMIN)
- if (Pred == CmpInst::ICMP_ULT && C == *C2 + SMin)
- return new ICmpInst(ICmpInst::ICMP_SGT, X, ConstantInt::get(Ty, ~(*C2)));
-
- // (X + C2) >s C --> X <u (SMAX - C) (if C == C2 - 1)
- if (Pred == CmpInst::ICMP_SGT && C == *C2 - 1)
- return new ICmpInst(ICmpInst::ICMP_ULT, X, ConstantInt::get(Ty, SMax - C));
-
- // (X + C2) <s C --> X >u (C ^ SMAX) (if C == C2)
- if (Pred == CmpInst::ICMP_SLT && C == *C2)
- return new ICmpInst(ICmpInst::ICMP_UGT, X, ConstantInt::get(Ty, C ^ SMax));
// If the add does not wrap, we can always adjust the compare by subtracting
// the constants. Equality comparisons are handled elsewhere. SGE/SLE/UGE/ULE
@@ -2703,6 +2684,28 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
return new ICmpInst(ICmpInst::ICMP_UGE, X, ConstantInt::get(Ty, Lower));
}
+ // This set of folds is intentionally placed after folds that use no-wrapping
+ // flags because those folds are likely better for later analysis/codegen.
+ const APInt SMax = APInt::getSignedMaxValue(Ty->getScalarSizeInBits());
+ const APInt SMin = APInt::getSignedMinValue(Ty->getScalarSizeInBits());
+
+ // Fold compare with offset to opposite sign compare if it eliminates offset:
+ // (X + C2) >u C --> X <s -C2 (if C == C2 + SMAX)
+ if (Pred == CmpInst::ICMP_UGT && C == *C2 + SMax)
+ return new ICmpInst(ICmpInst::ICMP_SLT, X, ConstantInt::get(Ty, -(*C2)));
+
+ // (X + C2) <u C --> X >s ~C2 (if C == C2 + SMIN)
+ if (Pred == CmpInst::ICMP_ULT && C == *C2 + SMin)
+ return new ICmpInst(ICmpInst::ICMP_SGT, X, ConstantInt::get(Ty, ~(*C2)));
+
+ // (X + C2) >s C --> X <u (SMAX - C) (if C == C2 - 1)
+ if (Pred == CmpInst::ICMP_SGT && C == *C2 - 1)
+ return new ICmpInst(ICmpInst::ICMP_ULT, X, ConstantInt::get(Ty, SMax - C));
+
+ // (X + C2) <s C --> X >u (C ^ SMAX) (if C == C2)
+ if (Pred == CmpInst::ICMP_SLT && C == *C2)
+ return new ICmpInst(ICmpInst::ICMP_UGT, X, ConstantInt::get(Ty, C ^ SMax));
+
if (!Add->hasOneUse())
return nullptr;
diff --git a/llvm/test/Transforms/InstCombine/icmp-add.ll b/llvm/test/Transforms/InstCombine/icmp-add.ll
index 3a9880697b21..c6dfb9d0e5d8 100644
--- a/llvm/test/Transforms/InstCombine/icmp-add.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-add.ll
@@ -796,7 +796,7 @@ define i1 @ugt_wrong_offset(i8 %a) {
define i1 @ugt_offset_nuw(i8 %a) {
; CHECK-LABEL: @ugt_offset_nuw(
-; CHECK-NEXT: [[OV:%.*]] = icmp slt i8 [[A:%.*]], -124
+; CHECK-NEXT: [[OV:%.*]] = icmp slt i8 [[A:%.*]], 0
; CHECK-NEXT: ret i1 [[OV]]
;
%t = add nuw i8 %a, 124
@@ -852,7 +852,7 @@ define i1 @ult_wrong_offset(i8 %a) {
define i1 @ult_offset_nuw(i8 %a) {
; CHECK-LABEL: @ult_offset_nuw(
-; CHECK-NEXT: [[OV:%.*]] = icmp sgt i8 [[A:%.*]], -43
+; CHECK-NEXT: [[OV:%.*]] = icmp sgt i8 [[A:%.*]], -1
; CHECK-NEXT: ret i1 [[OV]]
;
%t = add nuw i8 %a, 42
@@ -908,7 +908,7 @@ define i1 @sgt_wrong_offset(i8 %a) {
define i1 @sgt_offset_nsw(i8 %a, i8 %c) {
; CHECK-LABEL: @sgt_offset_nsw(
-; CHECK-NEXT: [[OV:%.*]] = icmp ult i8 [[A:%.*]], 86
+; CHECK-NEXT: [[OV:%.*]] = icmp sgt i8 [[A:%.*]], -1
; CHECK-NEXT: ret i1 [[OV]]
;
%t = add nsw i8 %a, 42
More information about the llvm-commits
mailing list