summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2022-01-12 14:58:24 -0500
committerSanjay Patel <spatel@rotateright.com>2022-01-12 14:59:43 -0500
commit6bd127b07916015c8d4f603344f06836abba57d8 (patch)
tree353ff71ccc1774e97a0f582586f5792c0cdd0ac1
parent56f62fbf73a2c0844d7f26ae10f2757aac981a2d (diff)
[InstSimplify] use knownbits to fold more udiv/urem
We could use knownbits on both operands for even more folds (and there are already tests in place for that), but this is enough to recover the example from: https://github.com/llvm/llvm-project/issues/51934 (the tests are derived from the code in that example) I am assuming no noticeable compile-time impact from this because udiv/urem are rare opcodes. Differential Revision: https://reviews.llvm.org/D116616
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp10
-rw-r--r--llvm/test/Transforms/InstSimplify/div.ll7
-rw-r--r--llvm/test/Transforms/InstSimplify/rem.ll5
3 files changed, 16 insertions, 6 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 7dc709e9e932..2986e0fa4ec1 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -1079,6 +1079,16 @@ static bool isDivZero(Value *X, Value *Y, const SimplifyQuery &Q,
}
// IsSigned == false.
+
+ // Is the unsigned dividend known to be less than a constant divisor?
+ // TODO: Convert this (and above) to range analysis
+ // ("computeConstantRangeIncludingKnownBits")?
+ const APInt *C;
+ if (match(Y, m_APInt(C)) &&
+ computeKnownBits(X, Q.DL, 0, Q.AC, Q.CxtI, Q.DT).getMaxValue().ult(*C))
+ return true;
+
+ // Try again for any divisor:
// Is the dividend unsigned less than the divisor?
return isICmpTrue(ICmpInst::ICMP_ULT, X, Y, Q, MaxRecurse);
}
diff --git a/llvm/test/Transforms/InstSimplify/div.ll b/llvm/test/Transforms/InstSimplify/div.ll
index c4e07d22e4a9..7eed067b284d 100644
--- a/llvm/test/Transforms/InstSimplify/div.ll
+++ b/llvm/test/Transforms/InstSimplify/div.ll
@@ -155,10 +155,7 @@ define i32 @not_udiv_constant_dividend_known_smaller_than_divisor(i32 %x) {
define i8 @udiv_dividend_known_smaller_than_constant_divisor2(i1 %b) {
; CHECK-LABEL: @udiv_dividend_known_smaller_than_constant_divisor2(
-; CHECK-NEXT: [[T0:%.*]] = zext i1 [[B:%.*]] to i8
-; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[T0]], 12
-; CHECK-NEXT: [[R:%.*]] = udiv i8 [[XOR]], 14
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 0
;
%t0 = zext i1 %b to i8
%xor = xor i8 %t0, 12
@@ -166,6 +163,8 @@ define i8 @udiv_dividend_known_smaller_than_constant_divisor2(i1 %b) {
ret i8 %r
}
+; negative test - dividend can equal 13
+
define i8 @not_udiv_dividend_known_smaller_than_constant_divisor2(i1 %b) {
; CHECK-LABEL: @not_udiv_dividend_known_smaller_than_constant_divisor2(
; CHECK-NEXT: [[T0:%.*]] = zext i1 [[B:%.*]] to i8
diff --git a/llvm/test/Transforms/InstSimplify/rem.ll b/llvm/test/Transforms/InstSimplify/rem.ll
index 9b7852d50cc4..011f991c9e02 100644
--- a/llvm/test/Transforms/InstSimplify/rem.ll
+++ b/llvm/test/Transforms/InstSimplify/rem.ll
@@ -187,8 +187,7 @@ define i8 @urem_dividend_known_smaller_than_constant_divisor2(i1 %b) {
; CHECK-LABEL: @urem_dividend_known_smaller_than_constant_divisor2(
; CHECK-NEXT: [[T0:%.*]] = zext i1 [[B:%.*]] to i8
; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[T0]], 12
-; CHECK-NEXT: [[R:%.*]] = urem i8 [[XOR]], 14
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[XOR]]
;
%t0 = zext i1 %b to i8
%xor = xor i8 %t0, 12
@@ -196,6 +195,8 @@ define i8 @urem_dividend_known_smaller_than_constant_divisor2(i1 %b) {
ret i8 %r
}
+; negative test - dividend can equal 13
+
define i8 @not_urem_dividend_known_smaller_than_constant_divisor2(i1 %b) {
; CHECK-LABEL: @not_urem_dividend_known_smaller_than_constant_divisor2(
; CHECK-NEXT: [[T0:%.*]] = zext i1 [[B:%.*]] to i8