mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-23 13:50:11 +00:00
[ValueTracking] Simplify uaddo pattern (#65910)
This patch simplifies the overflow check of unsigned addition. `a + b <u a` implies `a + b <u b` `a + b >=u a` implies `a + b >=u b` Alive2: https://alive2.llvm.org/ce/z/H8oK8n Fixes #65863.
This commit is contained in:
parent
4b4d3832b1
commit
9f2fc88b23
@ -8292,6 +8292,29 @@ static std::optional<bool> isImpliedCondICmps(const ICmpInst *LHS,
|
||||
if (L0 == R0 && match(L1, m_APInt(LC)) && match(R1, m_APInt(RC)))
|
||||
return isImpliedCondCommonOperandWithConstants(LPred, *LC, RPred, *RC);
|
||||
|
||||
// L0 = R0 = L1 + R1, L0 >=u L1 implies R0 >=u R1, L0 <u L1 implies R0 <u R1
|
||||
if (ICmpInst::isUnsigned(LPred) && ICmpInst::isUnsigned(RPred)) {
|
||||
if (L0 == R1) {
|
||||
std::swap(R0, R1);
|
||||
RPred = ICmpInst::getSwappedPredicate(RPred);
|
||||
}
|
||||
if (L1 == R0) {
|
||||
std::swap(L0, L1);
|
||||
LPred = ICmpInst::getSwappedPredicate(LPred);
|
||||
}
|
||||
if (L1 == R1) {
|
||||
std::swap(L0, L1);
|
||||
LPred = ICmpInst::getSwappedPredicate(LPred);
|
||||
std::swap(R0, R1);
|
||||
RPred = ICmpInst::getSwappedPredicate(RPred);
|
||||
}
|
||||
if (L0 == R0 &&
|
||||
(LPred == ICmpInst::ICMP_ULT || LPred == ICmpInst::ICMP_UGE) &&
|
||||
(RPred == ICmpInst::ICMP_ULT || RPred == ICmpInst::ICMP_UGE) &&
|
||||
match(L0, m_c_Add(m_Specific(L1), m_Specific(R1))))
|
||||
return LPred == RPred;
|
||||
}
|
||||
|
||||
if (LPred == RPred)
|
||||
return isImpliedCondOperands(LPred, L0, L1, R0, R1, DL, Depth);
|
||||
|
||||
|
@ -131,9 +131,7 @@ define i1 @uaddo_and(i64 %a, i64 %b){
|
||||
; CHECK-LABEL: @uaddo_and(
|
||||
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[COND_A:%.*]] = icmp uge i64 [[S]], [[A]]
|
||||
; CHECK-NEXT: [[COND_B:%.*]] = icmp uge i64 [[S]], [[B]]
|
||||
; CHECK-NEXT: [[COND:%.*]] = and i1 [[COND_A]], [[COND_B]]
|
||||
; CHECK-NEXT: ret i1 [[COND]]
|
||||
; CHECK-NEXT: ret i1 [[COND_A]]
|
||||
;
|
||||
%s = add i64 %a, %b
|
||||
%cond_a = icmp uge i64 %s, %a
|
||||
@ -146,9 +144,7 @@ define i1 @uaddo_and_commuted1(i64 %a, i64 %b){
|
||||
; CHECK-LABEL: @uaddo_and_commuted1(
|
||||
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[COND_A:%.*]] = icmp ule i64 [[A]], [[S]]
|
||||
; CHECK-NEXT: [[COND_B:%.*]] = icmp uge i64 [[S]], [[B]]
|
||||
; CHECK-NEXT: [[COND:%.*]] = and i1 [[COND_A]], [[COND_B]]
|
||||
; CHECK-NEXT: ret i1 [[COND]]
|
||||
; CHECK-NEXT: ret i1 [[COND_A]]
|
||||
;
|
||||
%s = add i64 %a, %b
|
||||
%cond_a = icmp ule i64 %a, %s
|
||||
@ -161,9 +157,7 @@ define i1 @uaddo_and_commuted2(i64 %a, i64 %b){
|
||||
; CHECK-LABEL: @uaddo_and_commuted2(
|
||||
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[COND_A:%.*]] = icmp uge i64 [[S]], [[A]]
|
||||
; CHECK-NEXT: [[COND_B:%.*]] = icmp ule i64 [[B]], [[S]]
|
||||
; CHECK-NEXT: [[COND:%.*]] = and i1 [[COND_A]], [[COND_B]]
|
||||
; CHECK-NEXT: ret i1 [[COND]]
|
||||
; CHECK-NEXT: ret i1 [[COND_A]]
|
||||
;
|
||||
%s = add i64 %a, %b
|
||||
%cond_a = icmp uge i64 %s, %a
|
||||
@ -176,9 +170,7 @@ define i1 @uaddo_and_commuted3(i64 %a, i64 %b){
|
||||
; CHECK-LABEL: @uaddo_and_commuted3(
|
||||
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[COND_A:%.*]] = icmp ule i64 [[A]], [[S]]
|
||||
; CHECK-NEXT: [[COND_B:%.*]] = icmp ule i64 [[B]], [[S]]
|
||||
; CHECK-NEXT: [[COND:%.*]] = and i1 [[COND_A]], [[COND_B]]
|
||||
; CHECK-NEXT: ret i1 [[COND]]
|
||||
; CHECK-NEXT: ret i1 [[COND_A]]
|
||||
;
|
||||
%s = add i64 %a, %b
|
||||
%cond_a = icmp ule i64 %a, %s
|
||||
@ -191,9 +183,7 @@ define i1 @uaddo_or(i64 %a, i64 %b){
|
||||
; CHECK-LABEL: @uaddo_or(
|
||||
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[COND_A:%.*]] = icmp ult i64 [[S]], [[A]]
|
||||
; CHECK-NEXT: [[COND_B:%.*]] = icmp ult i64 [[S]], [[B]]
|
||||
; CHECK-NEXT: [[COND:%.*]] = or i1 [[COND_A]], [[COND_B]]
|
||||
; CHECK-NEXT: ret i1 [[COND]]
|
||||
; CHECK-NEXT: ret i1 [[COND_A]]
|
||||
;
|
||||
%s = add i64 %a, %b
|
||||
%cond_a = icmp ult i64 %s, %a
|
||||
@ -206,9 +196,7 @@ define i1 @uaddo_or_commuted1(i64 %a, i64 %b){
|
||||
; CHECK-LABEL: @uaddo_or_commuted1(
|
||||
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[COND_A:%.*]] = icmp ugt i64 [[A]], [[S]]
|
||||
; CHECK-NEXT: [[COND_B:%.*]] = icmp ult i64 [[S]], [[B]]
|
||||
; CHECK-NEXT: [[COND:%.*]] = or i1 [[COND_A]], [[COND_B]]
|
||||
; CHECK-NEXT: ret i1 [[COND]]
|
||||
; CHECK-NEXT: ret i1 [[COND_A]]
|
||||
;
|
||||
%s = add i64 %a, %b
|
||||
%cond_a = icmp ugt i64 %a, %s
|
||||
@ -221,9 +209,7 @@ define i1 @uaddo_or_commuted2(i64 %a, i64 %b){
|
||||
; CHECK-LABEL: @uaddo_or_commuted2(
|
||||
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[COND_A:%.*]] = icmp ult i64 [[S]], [[A]]
|
||||
; CHECK-NEXT: [[COND_B:%.*]] = icmp ugt i64 [[B]], [[S]]
|
||||
; CHECK-NEXT: [[COND:%.*]] = or i1 [[COND_A]], [[COND_B]]
|
||||
; CHECK-NEXT: ret i1 [[COND]]
|
||||
; CHECK-NEXT: ret i1 [[COND_A]]
|
||||
;
|
||||
%s = add i64 %a, %b
|
||||
%cond_a = icmp ult i64 %s, %a
|
||||
@ -236,9 +222,7 @@ define i1 @uaddo_or_commuted3(i64 %a, i64 %b){
|
||||
; CHECK-LABEL: @uaddo_or_commuted3(
|
||||
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[COND_A:%.*]] = icmp ugt i64 [[A]], [[S]]
|
||||
; CHECK-NEXT: [[COND_B:%.*]] = icmp ugt i64 [[B]], [[S]]
|
||||
; CHECK-NEXT: [[COND:%.*]] = or i1 [[COND_A]], [[COND_B]]
|
||||
; CHECK-NEXT: ret i1 [[COND]]
|
||||
; CHECK-NEXT: ret i1 [[COND_A]]
|
||||
;
|
||||
%s = add i64 %a, %b
|
||||
%cond_a = icmp ugt i64 %a, %s
|
||||
|
Loading…
Reference in New Issue
Block a user