Skip to content

Commit 7668aa9

Browse files
committed
[InstCombine] Fold usub_sat((sub nuw C1, A), C2) to usub_sat(C1 - C2, A) or 0
1 parent 4ed5704 commit 7668aa9

File tree

2 files changed

+20
-8
lines changed

2 files changed

+20
-8
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2139,6 +2139,23 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
21392139
}
21402140
}
21412141

2142+
// usub_sat((sub nuw C1, A), C2) -> usub_sat(C1 - C2, A) if C2 u< C1
2143+
// usub_sat((sub nuw C1, A), C2) -> 0 otherwise
2144+
const APInt *C1, *C2;
2145+
Value *A;
2146+
if (IID == Intrinsic::usub_sat &&
2147+
match(Arg0, m_OneUse(m_NUWSub(m_APInt(C1), m_Value(A)))) &&
2148+
match(Arg1, m_APInt(C2)) && SI->hasOneUse()) {
2149+
2150+
if (C2->ult(*C1)) {
2151+
auto *New = Builder.CreateBinaryIntrinsic(
2152+
Intrinsic::usub_sat, ConstantInt::get(A->getType(), *C1 - *C2), A);
2153+
return replaceInstUsesWith(*SI, New);
2154+
} else {
2155+
return replaceInstUsesWith(*SI, ConstantInt::get(Ty, 0));
2156+
}
2157+
}
2158+
21422159
// ssub.sat(X, C) -> sadd.sat(X, -C) if C != MIN
21432160
Constant *C;
21442161
if (IID == Intrinsic::ssub_sat && match(Arg1, m_Constant(C)) &&

llvm/test/Transforms/InstCombine/unsigned_saturated_sub.ll

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ declare i16 @llvm.usub.sat.i16(i16, i16)
1414

1515
define i32 @usub_sat_C1_C2(i32 %a){
1616
; CHECK-LABEL: @usub_sat_C1_C2(
17-
; CHECK-NEXT: [[ADD:%.*]] = sub nuw i32 64, [[A:%.*]]
18-
; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[ADD]], i32 14)
17+
; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.usub.sat.i32(i32 50, i32 [[A:%.*]])
1918
; CHECK-NEXT: ret i32 [[COND]]
2019
;
2120
%add = sub nuw i32 64, %a
@@ -25,9 +24,7 @@ define i32 @usub_sat_C1_C2(i32 %a){
2524

2625
define i32 @usub_sat_C1_C2_produce_0(i32 %a){
2726
; CHECK-LABEL: @usub_sat_C1_C2_produce_0(
28-
; CHECK-NEXT: [[ADD:%.*]] = sub nuw i32 14, [[A:%.*]]
29-
; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[ADD]], i32 14)
30-
; CHECK-NEXT: ret i32 [[COND]]
27+
; CHECK-NEXT: ret i32 0
3128
;
3229
%add = sub nuw i32 14, %a
3330
%cond = call i32 @llvm.usub.sat.i32(i32 %add, i32 14)
@@ -36,9 +33,7 @@ define i32 @usub_sat_C1_C2_produce_0(i32 %a){
3633

3734
define i32 @usub_sat_C1_C2_produce_0_too(i32 %a){
3835
; CHECK-LABEL: @usub_sat_C1_C2_produce_0_too(
39-
; CHECK-NEXT: [[ADD:%.*]] = sub nuw i32 12, [[A:%.*]]
40-
; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[ADD]], i32 14)
41-
; CHECK-NEXT: ret i32 [[COND]]
36+
; CHECK-NEXT: ret i32 0
4237
;
4338
%add = sub nuw i32 12, %a
4439
%cond = call i32 @llvm.usub.sat.i32(i32 %add, i32 14)

0 commit comments

Comments
 (0)