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

via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 19 22:13:25 PST 2024


================
@@ -7,6 +7,77 @@
 declare void @use(i64)
 declare void @usei32(i32)
 declare void @usei1(i1)
+declare i32 @llvm.usub.sat.i32(i32, i32)
+declare i16 @llvm.usub.sat.i16(i16, i16)
+
+; usub_sat((sub nuw C1, A), C2) to usub_sat(C1 - C2, A) or 0
+
+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
+}
+
+; negative tests this souldn't work
+
+define i32 @usub_sat_C1_C2_without_nuw(i32 %a){
+; CHECK-LABEL: @usub_sat_C1_C2_without_nuw(
+; CHECK-NEXT:    [[ADD:%.*]] = sub i32 12, [[A:%.*]]
+; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[ADD]], i32 14)
+; CHECK-NEXT:    ret i32 [[COND]]
+;
+  %add = sub i32 12, %a
+  %cond = call i32 @llvm.usub.sat.i32(i32 %add, i32 14)
+  ret i32 %cond
+}
+
+define i32 @usub_sat_C1_C2_more_than_one_use_with_add(i32 %a){
+; CHECK-LABEL: @usub_sat_C1_C2_more_than_one_use_with_add(
+; CHECK-NEXT:    [[ADD:%.*]] = sub nuw i32 12, [[A:%.*]]
+; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[ADD]], i32 14)
+; CHECK-NEXT:    call void @usei32(i32 [[ADD]])
+; CHECK-NEXT:    ret i32 [[COND]]
+;
+  %add = sub nuw i32 12, %a
+  %cond = call i32 @llvm.usub.sat.i32(i32 %add, i32 14)
+  call void @usei32(i32 %add)
+  ret i32 %cond
+}
+
+define i32 @usub_sat_C1_C2_more_than_one_use_with_cond(i32 %a){
+; CHECK-LABEL: @usub_sat_C1_C2_more_than_one_use_with_cond(
+; CHECK-NEXT:    [[ADD:%.*]] = sub nuw i32 12, [[A:%.*]]
+; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[ADD]], i32 14)
+; CHECK-NEXT:    call void @usei32(i32 [[COND]])
+; CHECK-NEXT:    ret i32 [[COND]]
+;
+  %add = sub nuw i32 12, %a
+  %cond = call i32 @llvm.usub.sat.i32(i32 %add, i32 14)
+  call void @usei32(i32 %cond)
+  ret i32 %cond
+}
 
----------------
XChy wrote:

Can you please add:
- vector test
- test with commuted sub like (sub nuw i32 %a, 12), proof: https://alive2.llvm.org/ce/z/kVXDgW

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


More information about the llvm-commits mailing list