Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -191,13 +191,12 @@ bb.c: ; preds = %bb.b
_RNvMNtCs9BeaGo73rC4_16ruff_source_file10line_indexNtB2_9LineIndex10line_start.exit: ; preds = %bb.b
%i.k = getelementptr inbounds nuw [4 x i8], ptr %i.i, i64 %i.f
%i.l = load i32, ptr %i.k, align 4, !noalias !9, !noundef !3 ; 2 uses
%i.m = tail call i64 @llvm.uadd.sat.i64(i64 %1, i64 1)
%4 = add i64 %i.m, -1 ; 4 uses
%i.n = icmp eq i64 %4, %i.e
%i.m = tail call i64 @llvm.umin.i64(i64 %1, i64 -2) ; 4 uses
%i.n = icmp eq i64 %i.m, %i.e
br i1 %i.n, label %bb.e, label %bb.d

bb.d: ; preds = %_RNvMNtCs9BeaGo73rC4_16ruff_source_file10line_indexNtB2_9LineIndex10line_start.exit
%i.o = icmp ult i64 %4, %i.e
%i.o = icmp ult i64 %i.m, %i.e
br i1 %i.o, label %bb.g, label %bb.h

bb.e: ; preds = %_RNvMNtCs9BeaGo73rC4_16ruff_source_file10line_indexNtB2_9LineIndex10line_start.exit
Expand All @@ -219,12 +218,12 @@ _RNvXs_NtCs2MoD74u7shA_14ruff_text_size6traitsReNtB4_7TextLen8text_len.exit.i8:
br label %_RNvMNtCs9BeaGo73rC4_16ruff_source_file10line_indexNtB2_9LineIndex10line_start.exit11

bb.g: ; preds = %bb.d
%i.s = getelementptr inbounds nuw [4 x i8], ptr %i.i, i64 %4
%i.s = getelementptr inbounds nuw [4 x i8], ptr %i.i, i64 %i.m
%i.t = load i32, ptr %i.s, align 4, !noalias !18, !noundef !3
br label %_RNvMNtCs9BeaGo73rC4_16ruff_source_file10line_indexNtB2_9LineIndex10line_start.exit11

bb.h: ; preds = %bb.d
tail call void @_RNvNtCs4NRVxsYgnAr_4core9panicking18panic_bounds_check(i64 noundef %4, i64 noundef %i.e, ptr noalias noundef readonly align 8 captures(address, read_provenance) dereferenceable(24) @5) #18, !noalias !18
tail call void @_RNvNtCs4NRVxsYgnAr_4core9panicking18panic_bounds_check(i64 noundef %i.m, i64 noundef %i.e, ptr noalias noundef readonly align 8 captures(address, read_provenance) dereferenceable(24) @5) #18, !noalias !18
unreachable

_RNvMNtCs9BeaGo73rC4_16ruff_source_file10line_indexNtB2_9LineIndex10line_start.exit11: ; preds = %_RNvXs_NtCs2MoD74u7shA_14ruff_text_size6traitsReNtB4_7TextLen8text_len.exit.i8, %bb.g
Expand Down Expand Up @@ -626,6 +625,9 @@ declare hidden { i64, i64 } @_RINvMs2_NtNtCs2AWtUsOyxgP_3std6thread5localINtB6_8
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
declare void @llvm.experimental.noalias.scope.decl(metadata) #16

; Function Attrs: nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none)
declare i64 @llvm.umin.i64(i64, i64) #11

; Function Attrs: nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none)
declare i32 @llvm.umin.i32(i32, i32) #11

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,13 +203,12 @@ bb.c: ; preds = %bb.b
_RNvMNtCsdrxF8xh5sUs_16ruff_source_file10line_indexNtB2_9LineIndex10line_start.exit: ; preds = %bb.b
%i.k = getelementptr inbounds nuw [4 x i8], ptr %i.e, i64 %i.h
%i.l = load i32, ptr %i.k, align 4 ; 2 uses
%i.m = tail call i64 @llvm.uadd.sat.i64(i64 %1, i64 1)
%4 = add i64 %i.m, -1 ; 4 uses
%i.n = icmp eq i64 %4, %i.g
%i.m = tail call i64 @llvm.umin.i64(i64 %1, i64 -2) ; 4 uses
%i.n = icmp eq i64 %i.m, %i.g
br i1 %i.n, label %bb.e, label %bb.d

bb.d: ; preds = %_RNvMNtCsdrxF8xh5sUs_16ruff_source_file10line_indexNtB2_9LineIndex10line_start.exit
%i.o = icmp ult i64 %4, %i.g
%i.o = icmp ult i64 %i.m, %i.g
br i1 %i.o, label %bb.f, label %bb.g

bb.e: ; preds = %_RNvMNtCsdrxF8xh5sUs_16ruff_source_file10line_indexNtB2_9LineIndex10line_start.exit
Expand All @@ -232,12 +231,12 @@ _RNvXs_NtCs6jfqC49kXHE_14ruff_text_size6traitsReNtB4_7TextLen8text_lenCsdrxF8xh5
br label %_RNvMNtCsdrxF8xh5sUs_16ruff_source_file10line_indexNtB2_9LineIndex10line_start.exit8

bb.f: ; preds = %bb.d
%i.t = getelementptr inbounds nuw [4 x i8], ptr %i.e, i64 %4
%i.t = getelementptr inbounds nuw [4 x i8], ptr %i.e, i64 %i.m
%i.u = load i32, ptr %i.t, align 4
br label %_RNvMNtCsdrxF8xh5sUs_16ruff_source_file10line_indexNtB2_9LineIndex10line_start.exit8

bb.g: ; preds = %bb.d
tail call void @_RNvNtCs4NRVxsYgnAr_4core9panicking18panic_bounds_check(i64 %4, i64 %i.g, ptr nonnull align 8 @29) #37
tail call void @_RNvNtCs4NRVxsYgnAr_4core9panicking18panic_bounds_check(i64 %i.m, i64 %i.g, ptr nonnull align 8 @29) #37
unreachable

_RNvMNtCsdrxF8xh5sUs_16ruff_source_file10line_indexNtB2_9LineIndex10line_start.exit8: ; preds = %_RNvXs_NtCs6jfqC49kXHE_14ruff_text_size6traitsReNtB4_7TextLen8text_lenCsdrxF8xh5sUs_16ruff_source_file.exit.i4, %bb.f
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,6 @@ bb.r: ; preds = %bb.p, %bb.q
to label %bb.s unwind label %bb.g

bb.s: ; preds = %bb.r
%7 = tail call i64 @llvm.uadd.sat.i64(i64 %i.az, i64 1)
call void @llvm.lifetime.start.p0(ptr nonnull %i.a)
%i.ba = load ptr, ptr %i.c, align 8, !nonnull !4, !noundef !4 ; 3 uses
%i.bb = getelementptr inbounds nuw i8, ptr %i.ba, i64 48
Expand Down Expand Up @@ -246,8 +245,8 @@ bb.v: ; preds = %switch.lookup
bb.w: ; preds = %bb.v
%i.bq = icmp ne i64 %i.bl, 0
call void @llvm.assume(i1 %i.bq)
%8 = add i64 %7, -1
%i.br = call i64 @llvm.uadd.sat.i64(i64 %i.bl, i64 %8)
%7 = call i64 @llvm.umin.i64(i64 %i.az, i64 -2)
%i.br = call i64 @llvm.uadd.sat.i64(i64 %i.bl, i64 %7)
%i.bs = getelementptr inbounds nuw i8, ptr %0, i64 4
%i.bt = load i32, ptr %i.bs, align 4, !noundef !4
%i.bu = invoke noundef i64 @_RNvNtNtCsjNt1Wzngcv_9ty_server8document5range18u32_index_to_usize(i32 noundef %i.bt)
Expand Down Expand Up @@ -650,6 +649,9 @@ declare noundef zeroext i1 @_RNvXs0_NvXNvNtNtCsk4T2nMguaqB_13gen_lsp_types9gener
; Function Attrs: nonlazybind uwtable
declare noundef zeroext i1 @_RNvXsh_NtCs4NRVxsYgnAr_4core3fmteNtB5_5Debug3fmt(ptr noalias noundef nonnull readonly captures(address, read_provenance), i64 noundef, ptr noalias noundef align 8 dereferenceable(24)) unnamed_addr #0

; Function Attrs: nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none)
declare i64 @llvm.umin.i64(i64, i64) #10

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
declare void @llvm.experimental.noalias.scope.decl(metadata) #13

Expand Down
93 changes: 93 additions & 0 deletions report/z_patch.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 52a57e153bb4b..1d74547b5c6d0 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1003,7 +1003,17 @@ Instruction *InstCombinerImpl::foldAddWithConstant(BinaryOperator &Add) {
return replaceInstUsesWith(
Add, Builder.CreateBinaryIntrinsic(
Intrinsic::usub_sat, X, ConstantInt::get(Add.getType(), -*C)));
-
+ // uadd.sat(X, C) + -C --> umin(X, ~C)
+ // The saturating add gives X + C or UMAX, so subtracting C leaves X or
+ // UMAX - C. Note UMAX - C == ~C.
+ {
+ APInt SatC = -*C;
+ if (!SatC.isZero() && match(Op0, m_OneUse(m_Intrinsic<Intrinsic::uadd_sat>(
+ m_Value(X), m_SpecificInt(SatC)))))
+ return replaceInstUsesWith(
+ Add, Builder.CreateBinaryIntrinsic(Intrinsic::umin, X,
+ ConstantInt::get(Ty, ~SatC)));
+ }
// Fold (add (zext (add X, -C)), C) -> (zext X) if X u>= C.
// Truncate C to the narrow type to avoid mismatched width comparisons.
{
diff --git a/llvm/test/Transforms/InstCombine/saturating-add-sub.ll b/llvm/test/Transforms/InstCombine/saturating-add-sub.ll
index f1cc997a41ba1..341459ed94c9d 100644
--- a/llvm/test/Transforms/InstCombine/saturating-add-sub.ll
+++ b/llvm/test/Transforms/InstCombine/saturating-add-sub.ll
@@ -1367,15 +1367,65 @@ define i8 @test_scalar_uadd_sub_commuted_wrong(i8 %a, i8 %b) {

define i8 @test_scalar_uadd_sub_const(i8 %a) {
; CHECK-LABEL: @test_scalar_uadd_sub_const(
+; CHECK-NEXT: [[RES:%.*]] = call i8 @llvm.umin.i8(i8 [[A:%.*]], i8 -43)
+; CHECK-NEXT: ret i8 [[RES]]
+;
+ %sat = call i8 @llvm.uadd.sat.i8(i8 %a, i8 42)
+ %res = sub i8 %sat, 42
+ ret i8 %res
+}
+
+define <2 x i8> @test_vector_uadd_sub_const(<2 x i8> %a) {
+; CHECK-LABEL: @test_vector_uadd_sub_const(
+; CHECK-NEXT: [[RES:%.*]] = call <2 x i8> @llvm.umin.v2i8(<2 x i8> [[A:%.*]], <2 x i8> splat (i8 -43))
+; CHECK-NEXT: ret <2 x i8> [[RES]]
+;
+ %sat = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %a, <2 x i8> splat (i8 42))
+ %res = sub <2 x i8> %sat, splat (i8 42)
+ ret <2 x i8> %res
+}
+
+; negative test - the constants do not cancel
+
+define i8 @test_scalar_uadd_sub_const_mismatch(i8 %a) {
+; CHECK-LABEL: @test_scalar_uadd_sub_const_mismatch(
+; CHECK-NEXT: [[SAT:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[A:%.*]], i8 42)
+; CHECK-NEXT: [[RES:%.*]] = add i8 [[SAT]], -43
+; CHECK-NEXT: ret i8 [[RES]]
+;
+ %sat = call i8 @llvm.uadd.sat.i8(i8 %a, i8 42)
+ %res = sub i8 %sat, 43
+ ret i8 %res
+}
+
+; negative test - extra use of the saturating add
+
+define i8 @test_scalar_uadd_sub_const_multiuse(i8 %a) {
+; CHECK-LABEL: @test_scalar_uadd_sub_const_multiuse(
; CHECK-NEXT: [[SAT:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[A:%.*]], i8 42)
; CHECK-NEXT: [[RES:%.*]] = add i8 [[SAT]], -42
+; CHECK-NEXT: call void @usei8(i8 [[SAT]])
; CHECK-NEXT: ret i8 [[RES]]
;
%sat = call i8 @llvm.uadd.sat.i8(i8 %a, i8 42)
%res = sub i8 %sat, 42
+ call void @usei8(i8 %sat)
ret i8 %res
}

+; negative test - non-splat vector
+
+define <2 x i8> @test_vector_uadd_sub_const_nonsplat(<2 x i8> %a) {
+; CHECK-LABEL: @test_vector_uadd_sub_const_nonsplat(
+; CHECK-NEXT: [[SAT:%.*]] = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> <i8 42, i8 3>)
+; CHECK-NEXT: [[RES:%.*]] = add <2 x i8> [[SAT]], <i8 -42, i8 -3>
+; CHECK-NEXT: ret <2 x i8> [[RES]]
+;
+ %sat = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 42, i8 3>)
+ %res = sub <2 x i8> %sat, <i8 42, i8 3>
+ ret <2 x i8> %res
+}
+
define i1 @scalar_uadd_eq_zero(i8 %a, i8 %b) {
; CHECK-LABEL: @scalar_uadd_eq_zero(
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[A:%.*]], [[B:%.*]]
14 changes: 7 additions & 7 deletions report/z_stats.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@
"func-properties-stats.NumStoreInstCountPreOptimization": 68300725,
"func-properties-stats.NumTopLevelLoopCount": 1487055,
"func-properties-stats.NumTopLevelLoopCountPreOptimization": 1164636,
"func-properties-stats.NumTotalInstructionCount": 259349966,
"func-properties-stats.NumTotalInstructionCount": 259349963,
"func-properties-stats.NumTotalInstructionCountPreOptimization": 458831106,
"func-properties-stats.NumUses": 8712870,
"func-properties-stats.NumUsesPreOptimization": 53819668,
Expand Down Expand Up @@ -193,10 +193,10 @@
"globalopt.NumShrunkToBool": 6671,
"globalopt.NumUnnamed": 10931404,
"globalsmodref-aa.NumIndirectGlobalVars": 188,
"globalsmodref-aa.NumNoMemFunctions": 593579,
"globalsmodref-aa.NumNoMemFunctions": 593582,
"globalsmodref-aa.NumNonAddrTakenFunctions": 3051344,
"globalsmodref-aa.NumNonAddrTakenGlobalVars": 322037,
"globalsmodref-aa.NumReadMemFunctions": 954736,
"globalsmodref-aa.NumReadMemFunctions": 954739,
"gvn.IsValueFullyAvailableInBlockNumSpeculationsMax": 524423,
"gvn.NumGVNBlocks": 469912,
"gvn.NumGVNEqProp": 399193,
Expand Down Expand Up @@ -234,9 +234,9 @@
"instcombine.NegatorNumValuesVisited": 21403228,
"instcombine.NegatorTotalNegationsAttempted": 20122583,
"instcombine.NumAggregateReconstructionsSimplified": 26769,
"instcombine.NumCombined": 111301746,
"instcombine.NumCombined": 111301749,
"instcombine.NumConstProp": 157908,
"instcombine.NumDeadInst": 37456650,
"instcombine.NumDeadInst": 37456653,
"instcombine.NumDeadStore": 21890,
"instcombine.NumExpand": 3919,
"instcombine.NumFactor": 46339,
Expand All @@ -254,7 +254,7 @@
"instcount.LargestFunctionSizePreOptimization": 30754761,
"instcount.NumAShrInst": 344821,
"instcount.NumAShrInstPreOptimization": 82611,
"instcount.NumAddInst": 7854908,
"instcount.NumAddInst": 7854905,
"instcount.NumAddInstPreOptimization": 2665993,
"instcount.NumAllocaInst": 5404111,
"instcount.NumAllocaInstPreOptimization": 53100867,
Expand Down Expand Up @@ -375,7 +375,7 @@
"instcount.TotalBlocksPreOptimization": 69178949,
"instcount.TotalFuncs": 2936093,
"instcount.TotalFuncsPreOptimization": 15847031,
"instcount.TotalInsts": 259349966,
"instcount.TotalInsts": 259349963,
"instcount.TotalInstsPreOptimization": 461285542,
"instsimplify.NumExpand": 161127,
"instsimplify.NumReassoc": 921027,
Expand Down