1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

[InstSimplify] simplifyUnsignedRangeCheck(): handle few tautological cases (PR43251)

Summary:
This is split off from D67356, since these cases produce a constant,
no real need to keep them in instcombine.

Alive proofs:
https://rise4fun.com/Alive/u7Fk
https://rise4fun.com/Alive/4lV

https://bugs.llvm.org/show_bug.cgi?id=43251

Reviewers: spatel, nikic, xbolva00

Reviewed By: spatel

Subscribers: hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D67498

llvm-svn: 371921
This commit is contained in:
Roman Lebedev 2019-09-14 13:47:27 +00:00
parent 99be271bf5
commit e8dd40fec6
2 changed files with 42 additions and 27 deletions

View File

@ -1382,11 +1382,31 @@ static Value *simplifyUnsignedRangeCheck(ICmpInst *ZeroICmp,
ICmpInst::Predicate UnsignedPred;
// Y = (A - B); Y >= A && Y != 0 --> Y >= A iff B != 0
// Y = (A - B); Y < A || Y == 0 --> Y < A iff B != 0
Value *A, *B;
if (match(Y, m_Sub(m_Value(A), m_Value(B))) &&
match(UnsignedICmp,
// Y = (A - B);
if (match(Y, m_Sub(m_Value(A), m_Value(B)))) {
if (match(UnsignedICmp,
m_c_ICmp(UnsignedPred, m_Specific(A), m_Specific(B))) &&
ICmpInst::isUnsigned(UnsignedPred)) {
if (UnsignedICmp->getOperand(0) != A)
UnsignedPred = ICmpInst::getSwappedPredicate(UnsignedPred);
// A >=/<= B || (A - B) != 0 <--> true
if ((UnsignedPred == ICmpInst::ICMP_UGE ||
UnsignedPred == ICmpInst::ICMP_ULE) &&
EqPred == ICmpInst::ICMP_NE && !IsAnd)
return ConstantInt::getTrue(UnsignedICmp->getType());
// A </> B && (A - B) == 0 <--> false
if ((UnsignedPred == ICmpInst::ICMP_ULT ||
UnsignedPred == ICmpInst::ICMP_UGT) &&
EqPred == ICmpInst::ICMP_EQ && IsAnd)
return ConstantInt::getFalse(UnsignedICmp->getType());
}
// Given Y = (A - B)
// Y >= A && Y != 0 --> Y >= A iff B != 0
// Y < A || Y == 0 --> Y < A iff B != 0
if (match(UnsignedICmp,
m_c_ICmp(UnsignedPred, m_Specific(Y), m_Specific(A)))) {
if (UnsignedICmp->getOperand(0) != Y)
UnsignedPred = ICmpInst::getSwappedPredicate(UnsignedPred);
@ -1400,6 +1420,7 @@ static Value *simplifyUnsignedRangeCheck(ICmpInst *ZeroICmp,
isKnownNonZero(B, Q.DL, /*Depth=*/0, Q.AC, Q.CxtI, Q.DT))
return UnsignedICmp;
}
}
if (match(UnsignedICmp, m_ICmp(UnsignedPred, m_Value(X), m_Specific(Y))) &&
ICmpInst::isUnsigned(UnsignedPred))

View File

@ -22,8 +22,7 @@ define i1 @t1(i8 %base, i8 %offset) {
; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]])
; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0
; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]])
; CHECK-NEXT: [[R:%.*]] = or i1 [[NOT_NULL]], [[NO_UNDERFLOW]]
; CHECK-NEXT: ret i1 [[R]]
; CHECK-NEXT: ret i1 true
;
%adjusted = sub i8 %base, %offset
call void @use8(i8 %adjusted)
@ -62,8 +61,7 @@ define i1 @t1_commutativity(i8 %base, i8 %offset) {
; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]])
; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0
; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]])
; CHECK-NEXT: [[R:%.*]] = or i1 [[NOT_NULL]], [[NO_UNDERFLOW]]
; CHECK-NEXT: ret i1 [[R]]
; CHECK-NEXT: ret i1 true
;
%adjusted = sub i8 %base, %offset
call void @use8(i8 %adjusted)
@ -86,8 +84,7 @@ define i1 @t2(i8 %base, i8 %offset) {
; CHECK-NEXT: call void @use1(i1 [[UNDERFLOW]])
; CHECK-NEXT: [[NULL:%.*]] = icmp eq i8 [[ADJUSTED]], 0
; CHECK-NEXT: call void @use1(i1 [[NULL]])
; CHECK-NEXT: [[R:%.*]] = and i1 [[NULL]], [[UNDERFLOW]]
; CHECK-NEXT: ret i1 [[R]]
; CHECK-NEXT: ret i1 false
;
%adjusted = sub i8 %base, %offset
call void @use8(i8 %adjusted)
@ -126,8 +123,7 @@ define i1 @t2_commutativity(i8 %base, i8 %offset) {
; CHECK-NEXT: call void @use1(i1 [[UNDERFLOW]])
; CHECK-NEXT: [[NULL:%.*]] = icmp eq i8 [[ADJUSTED]], 0
; CHECK-NEXT: call void @use1(i1 [[NULL]])
; CHECK-NEXT: [[R:%.*]] = and i1 [[NULL]], [[UNDERFLOW]]
; CHECK-NEXT: ret i1 [[R]]
; CHECK-NEXT: ret i1 false
;
%adjusted = sub i8 %base, %offset
call void @use8(i8 %adjusted)
@ -148,8 +144,7 @@ define i1 @t3(i8 %base, i8 %offset) {
; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]])
; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0
; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]])
; CHECK-NEXT: [[R:%.*]] = or i1 [[NOT_NULL]], [[NO_UNDERFLOW]]
; CHECK-NEXT: ret i1 [[R]]
; CHECK-NEXT: ret i1 true
;
%adjusted = sub i8 %base, %offset
call void @use8(i8 %adjusted)
@ -170,8 +165,7 @@ define i1 @t4(i8 %base, i8 %offset) {
; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]])
; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp eq i8 [[ADJUSTED]], 0
; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]])
; CHECK-NEXT: [[R:%.*]] = and i1 [[NOT_NULL]], [[NO_UNDERFLOW]]
; CHECK-NEXT: ret i1 [[R]]
; CHECK-NEXT: ret i1 false
;
%adjusted = sub i8 %base, %offset
call void @use8(i8 %adjusted)