[llvm] r292952 - [InstSimplify] try to eliminate icmp Pred (add nsw X, C1), C2
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 24 09:03:24 PST 2017
Author: spatel
Date: Tue Jan 24 11:03:24 2017
New Revision: 292952
URL: http://llvm.org/viewvc/llvm-project?rev=292952&view=rev
Log:
[InstSimplify] try to eliminate icmp Pred (add nsw X, C1), C2
I was surprised to see that we're missing icmp folds based on 'add nsw' in InstCombine,
but we should handle the InstSimplify cases first because that could make the InstCombine
code simpler.
Here are Alive-based proofs for the logic:
Name: add_neg_constant
Pre: C1 < 0 && (C2 > ((1<<(width(C1)-1)) + C1))
%a = add nsw i7 %x, C1
%b = icmp sgt %a, C2
=>
%b = false
Name: add_pos_constant
Pre: C1 > 0 && (C2 < ((1<<(width(C1)-1)) + C1 - 1))
%a = add nsw i6 %x, C1
%b = icmp slt %a, C2
=>
%b = false
Name: nuw
Pre: C1 u>= C2
%a = add nuw i11 %x, C1
%b = icmp ult %a, C2
=>
%b = false
Differential Revision: https://reviews.llvm.org/D29053
Modified:
llvm/trunk/lib/Analysis/InstructionSimplify.cpp
llvm/trunk/test/Transforms/InstSimplify/icmp-constant.ll
Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=292952&r1=292951&r2=292952&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
+++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Tue Jan 24 11:03:24 2017
@@ -2385,9 +2385,23 @@ static void setLimitsForBinOp(BinaryOper
const APInt *C;
switch (BO.getOpcode()) {
case Instruction::Add:
- if (BO.hasNoUnsignedWrap() && match(BO.getOperand(1), m_APInt(C)))
- // 'add nuw x, C' produces [C, UINT_MAX].
- Lower = *C;
+ if (match(BO.getOperand(1), m_APInt(C)) && *C != 0) {
+ // FIXME: If we have both nuw and nsw, we should reduce the range further.
+ if (BO.hasNoUnsignedWrap()) {
+ // 'add nuw x, C' produces [C, UINT_MAX].
+ Lower = *C;
+ } else if (BO.hasNoSignedWrap()) {
+ if (C->isNegative()) {
+ // 'add nsw x, -C' produces [SINT_MIN, SINT_MAX - C].
+ Lower = APInt::getSignedMinValue(Width);
+ Upper = APInt::getSignedMaxValue(Width) + *C + 1;
+ } else {
+ // 'add nsw x, +C' produces [SINT_MIN + C, SINT_MAX].
+ Lower = APInt::getSignedMinValue(Width) + *C;
+ Upper = APInt::getSignedMaxValue(Width) + 1;
+ }
+ }
+ }
break;
case Instruction::And:
Modified: llvm/trunk/test/Transforms/InstSimplify/icmp-constant.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/icmp-constant.ll?rev=292952&r1=292951&r2=292952&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/icmp-constant.ll (original)
+++ llvm/trunk/test/Transforms/InstSimplify/icmp-constant.ll Tue Jan 24 11:03:24 2017
@@ -420,9 +420,7 @@ define <2 x i1> @tautological9_vec(<2 x
define i1 @add_nsw_neg_const1(i32 %x) {
; CHECK-LABEL: @add_nsw_neg_const1(
-; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 %x, -2147483647
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[ADD]], 0
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 false
;
%add = add nsw i32 %x, -2147483647
%cmp = icmp sgt i32 %add, 0
@@ -446,9 +444,7 @@ define i1 @add_nsw_neg_const2(i32 %x) {
define i1 @add_nsw_neg_const3(i32 %x) {
; CHECK-LABEL: @add_nsw_neg_const3(
-; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 %x, -2147483646
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[ADD]], 1
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 false
;
%add = add nsw i32 %x, -2147483646
%cmp = icmp sgt i32 %add, 1
@@ -472,9 +468,7 @@ define i1 @add_nsw_neg_const4(i32 %x) {
define i1 @add_nsw_neg_const5(i32 %x) {
; CHECK-LABEL: @add_nsw_neg_const5(
-; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 %x, -42
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[ADD]], 2147483606
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 true
;
%add = add nsw i32 %x, -42
%cmp = icmp ne i32 %add, 2147483606
@@ -498,9 +492,7 @@ define i1 @add_nsw_neg_const6(i32 %x) {
define i1 @add_nsw_pos_const1(i32 %x) {
; CHECK-LABEL: @add_nsw_pos_const1(
-; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 %x, 2147483647
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD]], -1
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 false
;
%add = add nsw i32 %x, 2147483647
%cmp = icmp slt i32 %add, -1
@@ -524,9 +516,7 @@ define i1 @add_nsw_pos_const2(i32 %x) {
define i1 @add_nsw_pos_const3(i32 %x) {
; CHECK-LABEL: @add_nsw_pos_const3(
-; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 %x, 2147483646
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD]], -2
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 false
;
%add = add nsw i32 %x, 2147483646
%cmp = icmp slt i32 %add, -2
@@ -550,9 +540,7 @@ define i1 @add_nsw_pos_const4(i32 %x) {
define i1 @add_nsw_pos_const5(i32 %x) {
; CHECK-LABEL: @add_nsw_pos_const5(
-; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 %x, 42
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[ADD]], -2147483607
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 false
;
%add = add nsw i32 %x, 42
%cmp = icmp eq i32 %add, -2147483607
@@ -576,9 +564,7 @@ define i1 @add_nsw_pos_const6(i32 %x) {
define <2 x i1> @add_nsw_pos_const5_splat_vec(<2 x i32> %x) {
; CHECK-LABEL: @add_nsw_pos_const5_splat_vec(
-; CHECK-NEXT: [[ADD:%.*]] = add nsw <2 x i32> %x, <i32 42, i32 42>
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[ADD]], <i32 -2147483607, i32 -2147483607>
-; CHECK-NEXT: ret <2 x i1> [[CMP]]
+; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
;
%add = add nsw <2 x i32> %x, <i32 42, i32 42>
%cmp = icmp ne <2 x i32> %add, <i32 -2147483607, i32 -2147483607>
More information about the llvm-commits
mailing list