From c3b4ae6531eaeb9841759a9c15fd3d63b0f17782 Mon Sep 17 00:00:00 2001 From: Poseydon42 Date: Tue, 13 Aug 2024 23:01:11 +0100 Subject: [PATCH 1/4] Precommit tests --- llvm/test/Transforms/InstCombine/icmp-add.ll | 71 ++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/llvm/test/Transforms/InstCombine/icmp-add.ll b/llvm/test/Transforms/InstCombine/icmp-add.ll index baa6f3d51a40e..88ccda417763e 100644 --- a/llvm/test/Transforms/InstCombine/icmp-add.ll +++ b/llvm/test/Transforms/InstCombine/icmp-add.ll @@ -3102,3 +3102,74 @@ define i1 @uge_add_C2_pow2_C_neg(i8 %x) { } declare void @llvm.assume(i1) + +; Change an unsigned predicate to signed in icmp (add x, C1), C2 +define i1 @icmp_add_constant_with_constant_ult_to_slt(i32 range(i32 -4, 10) %x) { +; CHECK-LABEL: @icmp_add_constant_with_constant_ult_to_slt( +; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], 5 +; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], 13 +; CHECK-NEXT: ret i1 [[CMP]] +; + %add = add nsw i32 %x, 5 + %cmp = icmp ult i32 %add, 13 + ret i1 %cmp +} + +define i1 @icmp_add_constant_with_constant_ugt_to_sgt(i32 range(i32 -4, 10) %x) { +; CHECK-LABEL: @icmp_add_constant_with_constant_ugt_to_sgt( +; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[X:%.*]], -3 +; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP1]], -13 +; CHECK-NEXT: ret i1 [[CMP]] +; + %add = add nsw i32 %x, 10 + %cmp = icmp ugt i32 %add, 12 + ret i1 %cmp +} + +; Negative test: x + C1 may be negative +define i1 @icmp_add_constant_with_constant_ult_to_slt_neg1(i32 range(i32 -5, 10) %x) { +; CHECK-LABEL: @icmp_add_constant_with_constant_ult_to_slt_neg1( +; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], 4 +; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], 20 +; CHECK-NEXT: ret i1 [[CMP]] +; + %add = add nsw i32 %x, 4 + %cmp = icmp ult i32 %add, 20 + ret i1 %cmp +} + +; Negative test: missing nsw flag +define i1 @icmp_add_constant_with_constant_ult_to_slt_neg2(i8 range(i8 -4, 120) %x) { +; CHECK-LABEL: @icmp_add_constant_with_constant_ult_to_slt_neg2( +; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X:%.*]], 15 +; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[ADD]], 20 +; CHECK-NEXT: ret i1 [[CMP]] +; + %add = add i8 %x, 15 + %cmp = icmp ult i8 %add, 20 + ret i1 %cmp +} + +; Negative test: C2 is negative +define i1 @icmp_add_constant_with_constant_ult_to_slt_neg3(i32 range(i32 -4, 10) %x) { +; CHECK-LABEL: @icmp_add_constant_with_constant_ult_to_slt_neg3( +; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], 4 +; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], -6 +; CHECK-NEXT: ret i1 [[CMP]] +; + %add = add nsw i32 %x, 4 + %cmp = icmp ult i32 %add, -6 + ret i1 %cmp +} + +; Negative test: C2 - C1 is negative +define i1 @icmp_add_constant_with_constant_ult_to_slt_neg4(i32 range(i32 -4, 10) %x) { +; CHECK-LABEL: @icmp_add_constant_with_constant_ult_to_slt_neg4( +; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], 5 +; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], 2 +; CHECK-NEXT: ret i1 [[CMP]] +; + %add = add nsw i32 %x, 5 + %cmp = icmp ult i32 %add, 2 + ret i1 %cmp +} From 12f5eff910e56ab59e0285131bf0b92a2b3eb883 Mon Sep 17 00:00:00 2001 From: Poseydon42 Date: Tue, 13 Aug 2024 23:03:46 +0100 Subject: [PATCH 2/4] Implement fold & update tests --- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 7 +++++++ llvm/test/Transforms/InstCombine/icmp-add.ll | 6 ++---- llvm/test/Transforms/LoopVectorize/interleaved-accesses.ll | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 10a89b47e0753..b7eac02dd2174 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -3077,6 +3077,13 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp, return new ICmpInst(Pred, X, ConstantInt::get(Ty, NewC)); } + ConstantRange LHS_CR = computeConstantRange(X, true).add(*C2); + if (ICmpInst::isUnsigned(Pred) && Add->hasNoSignedWrap() && + C.isNonNegative() && LHS_CR.isAllNonNegative() && + (C - *C2).isNonNegative()) + return new ICmpInst(ICmpInst::getSignedPredicate(Pred), X, + ConstantInt::get(Ty, C - *C2)); + auto CR = ConstantRange::makeExactICmpRegion(Pred, C).subtract(*C2); const APInt &Upper = CR.getUpper(); const APInt &Lower = CR.getLower(); diff --git a/llvm/test/Transforms/InstCombine/icmp-add.ll b/llvm/test/Transforms/InstCombine/icmp-add.ll index 88ccda417763e..07e7756915b45 100644 --- a/llvm/test/Transforms/InstCombine/icmp-add.ll +++ b/llvm/test/Transforms/InstCombine/icmp-add.ll @@ -3106,8 +3106,7 @@ declare void @llvm.assume(i1) ; Change an unsigned predicate to signed in icmp (add x, C1), C2 define i1 @icmp_add_constant_with_constant_ult_to_slt(i32 range(i32 -4, 10) %x) { ; CHECK-LABEL: @icmp_add_constant_with_constant_ult_to_slt( -; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], 5 -; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], 13 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 8 ; CHECK-NEXT: ret i1 [[CMP]] ; %add = add nsw i32 %x, 5 @@ -3117,8 +3116,7 @@ define i1 @icmp_add_constant_with_constant_ult_to_slt(i32 range(i32 -4, 10) %x) define i1 @icmp_add_constant_with_constant_ugt_to_sgt(i32 range(i32 -4, 10) %x) { ; CHECK-LABEL: @icmp_add_constant_with_constant_ugt_to_sgt( -; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[X:%.*]], -3 -; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP1]], -13 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], 2 ; CHECK-NEXT: ret i1 [[CMP]] ; %add = add nsw i32 %x, 10 diff --git a/llvm/test/Transforms/LoopVectorize/interleaved-accesses.ll b/llvm/test/Transforms/LoopVectorize/interleaved-accesses.ll index 61ed955ea13e4..6fc52ab3f26e0 100644 --- a/llvm/test/Transforms/LoopVectorize/interleaved-accesses.ll +++ b/llvm/test/Transforms/LoopVectorize/interleaved-accesses.ll @@ -1359,7 +1359,7 @@ define void @PR27626_5(ptr %a, i32 %x, i32 %y, i32 %z, i64 %n) { ; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 [[SMAX]], -4 ; CHECK-NEXT: [[TMP1:%.*]] = lshr i64 [[TMP0]], 1 ; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i64 [[TMP1]], 1 -; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 6 +; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp slt i64 [[N]], 10 ; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; CHECK: vector.ph: ; CHECK-NEXT: [[N_VEC:%.*]] = and i64 [[TMP2]], 9223372036854775804 From 3b07a693ca778bfb5769d91bdfe4facd10106413 Mon Sep 17 00:00:00 2001 From: Poseydon42 Date: Wed, 14 Aug 2024 11:23:30 +0100 Subject: [PATCH 3/4] Address review comments --- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index b7eac02dd2174..cbe602183504d 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -3077,10 +3077,9 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp, return new ICmpInst(Pred, X, ConstantInt::get(Ty, NewC)); } - ConstantRange LHS_CR = computeConstantRange(X, true).add(*C2); if (ICmpInst::isUnsigned(Pred) && Add->hasNoSignedWrap() && - C.isNonNegative() && LHS_CR.isAllNonNegative() && - (C - *C2).isNonNegative()) + C.isNonNegative() && (C - *C2).isNonNegative() && + computeConstantRange(X, /*ForSigned=*/true).add(*C2).isAllNonNegative()) return new ICmpInst(ICmpInst::getSignedPredicate(Pred), X, ConstantInt::get(Ty, C - *C2)); From c3f7535595049de89937203830ddedf7918b0a39 Mon Sep 17 00:00:00 2001 From: Poseydon42 Date: Wed, 14 Aug 2024 13:55:53 +0100 Subject: [PATCH 4/4] Add test --- llvm/test/Transforms/InstCombine/icmp-add.ll | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/llvm/test/Transforms/InstCombine/icmp-add.ll b/llvm/test/Transforms/InstCombine/icmp-add.ll index 07e7756915b45..2ceb44b89eb9e 100644 --- a/llvm/test/Transforms/InstCombine/icmp-add.ll +++ b/llvm/test/Transforms/InstCombine/icmp-add.ll @@ -3171,3 +3171,15 @@ define i1 @icmp_add_constant_with_constant_ult_to_slt_neg4(i32 range(i32 -4, 10) %cmp = icmp ult i32 %add, 2 ret i1 %cmp } + +; Same as before, but infer the range of ucmp +define i1 @icmp_of_ucmp_plus_const_with_const(i32 %x, i32 %y) { +; CHECK-LABEL: @icmp_of_ucmp_plus_const_with_const( +; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[CMP2]] +; + %cmp1 = call i8 @llvm.ucmp(i32 %x, i32 %y) + %add = add i8 %cmp1, 1 + %cmp2 = icmp ult i8 %add, 2 + ret i1 %cmp2 +}