forked from OSchip/llvm-project
[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
This commit is contained in:
parent
56f62fbf73
commit
6bd127b079
|
@ -1079,6 +1079,16 @@ static bool isDivZero(Value *X, Value *Y, const SimplifyQuery &Q,
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsSigned == false.
|
// 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?
|
// Is the dividend unsigned less than the divisor?
|
||||||
return isICmpTrue(ICmpInst::ICMP_ULT, X, Y, Q, MaxRecurse);
|
return isICmpTrue(ICmpInst::ICMP_ULT, X, Y, Q, MaxRecurse);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
define i8 @udiv_dividend_known_smaller_than_constant_divisor2(i1 %b) {
|
||||||
; CHECK-LABEL: @udiv_dividend_known_smaller_than_constant_divisor2(
|
; CHECK-LABEL: @udiv_dividend_known_smaller_than_constant_divisor2(
|
||||||
; CHECK-NEXT: [[T0:%.*]] = zext i1 [[B:%.*]] to i8
|
; CHECK-NEXT: ret i8 0
|
||||||
; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[T0]], 12
|
|
||||||
; CHECK-NEXT: [[R:%.*]] = udiv i8 [[XOR]], 14
|
|
||||||
; CHECK-NEXT: ret i8 [[R]]
|
|
||||||
;
|
;
|
||||||
%t0 = zext i1 %b to i8
|
%t0 = zext i1 %b to i8
|
||||||
%xor = xor i8 %t0, 12
|
%xor = xor i8 %t0, 12
|
||||||
|
@ -166,6 +163,8 @@ define i8 @udiv_dividend_known_smaller_than_constant_divisor2(i1 %b) {
|
||||||
ret i8 %r
|
ret i8 %r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; negative test - dividend can equal 13
|
||||||
|
|
||||||
define i8 @not_udiv_dividend_known_smaller_than_constant_divisor2(i1 %b) {
|
define i8 @not_udiv_dividend_known_smaller_than_constant_divisor2(i1 %b) {
|
||||||
; CHECK-LABEL: @not_udiv_dividend_known_smaller_than_constant_divisor2(
|
; CHECK-LABEL: @not_udiv_dividend_known_smaller_than_constant_divisor2(
|
||||||
; CHECK-NEXT: [[T0:%.*]] = zext i1 [[B:%.*]] to i8
|
; CHECK-NEXT: [[T0:%.*]] = zext i1 [[B:%.*]] to i8
|
||||||
|
|
|
@ -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-LABEL: @urem_dividend_known_smaller_than_constant_divisor2(
|
||||||
; CHECK-NEXT: [[T0:%.*]] = zext i1 [[B:%.*]] to i8
|
; CHECK-NEXT: [[T0:%.*]] = zext i1 [[B:%.*]] to i8
|
||||||
; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[T0]], 12
|
; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[T0]], 12
|
||||||
; CHECK-NEXT: [[R:%.*]] = urem i8 [[XOR]], 14
|
; CHECK-NEXT: ret i8 [[XOR]]
|
||||||
; CHECK-NEXT: ret i8 [[R]]
|
|
||||||
;
|
;
|
||||||
%t0 = zext i1 %b to i8
|
%t0 = zext i1 %b to i8
|
||||||
%xor = xor i8 %t0, 12
|
%xor = xor i8 %t0, 12
|
||||||
|
@ -196,6 +195,8 @@ define i8 @urem_dividend_known_smaller_than_constant_divisor2(i1 %b) {
|
||||||
ret i8 %r
|
ret i8 %r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; negative test - dividend can equal 13
|
||||||
|
|
||||||
define i8 @not_urem_dividend_known_smaller_than_constant_divisor2(i1 %b) {
|
define i8 @not_urem_dividend_known_smaller_than_constant_divisor2(i1 %b) {
|
||||||
; CHECK-LABEL: @not_urem_dividend_known_smaller_than_constant_divisor2(
|
; CHECK-LABEL: @not_urem_dividend_known_smaller_than_constant_divisor2(
|
||||||
; CHECK-NEXT: [[T0:%.*]] = zext i1 [[B:%.*]] to i8
|
; CHECK-NEXT: [[T0:%.*]] = zext i1 [[B:%.*]] to i8
|
||||||
|
|
Loading…
Reference in New Issue