[llvm] [InstCombine] Fold usub_sat((sub nuw C1, A), C2) to usub_sat(C1 - C2, A) or 0 (PR #82280)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 11 04:56:11 PDT 2024


================
@@ -8,6 +8,85 @@ declare void @use(i64)
 declare void @usei32(i32)
 declare void @usei1(i1)
 
+; usub_sat((sub nuw C1, A), C2) to usub_sat(usub_sat(C1 - C2), A)
+define i32 @usub_sat_C1_C2(i32 %a){
+; CHECK-LABEL: @usub_sat_C1_C2(
+; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.usub.sat.i32(i32 50, i32 [[A:%.*]])
+; CHECK-NEXT:    ret i32 [[COND]]
+;
+  %add = sub nuw i32 64, %a
+  %cond = call i32 @llvm.usub.sat.i32(i32 %add, i32 14)
+  ret i32 %cond
+}
+
+define i32 @usub_sat_C1_C2_produce_0(i32 %a){
+; CHECK-LABEL: @usub_sat_C1_C2_produce_0(
+; CHECK-NEXT:    ret i32 0
+;
+  %add = sub nuw i32 14, %a
+  %cond = call i32 @llvm.usub.sat.i32(i32 %add, i32 14)
+  ret i32 %cond
+}
+
+define i32 @usub_sat_C1_C2_produce_0_too(i32 %a){
+; CHECK-LABEL: @usub_sat_C1_C2_produce_0_too(
+; CHECK-NEXT:    ret i32 0
+;
+  %add = sub nuw i32 12, %a
+  %cond = call i32 @llvm.usub.sat.i32(i32 %add, i32 14)
+  ret i32 %cond
+}
+
+; vector tests
+define <2 x i16> @usub_sat_C1_C2_splat(<2 x i16> %a) {
+; CHECK-LABEL: @usub_sat_C1_C2_splat(
+; CHECK-NEXT:    [[COND:%.*]] = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> <i16 50, i16 50>, <2 x i16> [[A:%.*]])
+; CHECK-NEXT:    ret <2 x i16> [[COND]]
+;
+  %add = sub nuw <2 x i16> <i16 64, i16 64>, %a
+  %cond = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %add, <2 x i16> <i16 14, i16 14>)
+  ret <2 x i16> %cond
+}
+
+define <2 x i16> @usub_sat_C1_C2_splat_produce_0(<2 x i16> %a){
+; CHECK-LABEL: @usub_sat_C1_C2_splat_produce_0(
+; CHECK-NEXT:    ret <2 x i16> zeroinitializer
+;
+  %add = sub nuw <2 x i16> <i16 14, i16 14>, %a
+  %cond = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %add, <2 x i16> <i16 14, i16 14>)
+  ret <2 x i16> %cond
+}
+
+define <2 x i16> @usub_sat_C1_C2_splat_produce_0_too(<2 x i16> %a){
+; CHECK-LABEL: @usub_sat_C1_C2_splat_produce_0_too(
+; CHECK-NEXT:    ret <2 x i16> zeroinitializer
+;
+  %add = sub nuw <2 x i16> <i16 12, i16 12>, %a
+  %cond = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %add, <2 x i16> <i16 14, i16 14>)
+  ret <2 x i16> %cond
+}
+
+define <2 x i16> @usub_sat_C1_C2_non_splat_produce_0_too(<2 x i16> %a){
+; CHECK-LABEL: @usub_sat_C1_C2_non_splat_produce_0_too(
+; CHECK-NEXT:    ret <2 x i16> zeroinitializer
+;
+  %add = sub nuw <2 x i16> <i16 12, i16 13>, %a
+  %cond = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %add, <2 x i16> <i16 14, i16 15>)
+  ret <2 x i16> %cond
+}
----------------
nikic wrote:

Could you please also add a non-splat test where the result is not zero?

https://github.com/llvm/llvm-project/pull/82280


More information about the llvm-commits mailing list