[PATCH] D69514: [InstCombine] Expand usub_sat patterns to handle constants
Dave Green via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 28 08:36:23 PDT 2019
dmgreen created this revision.
dmgreen added reviewers: nikic, lebedev.ri, spatel.
Herald added a subscriber: hiraditya.
Herald added a project: LLVM.
The constants come through as add %x, -C, not a sub as would be expected. They need some extra matchers to canonicalise them towards usub_sat.
----------------------------------------
Optimization: Forwards
Precondition: true
%cmp = icmp ugt i32 %a, 9
%sub = add i32 %a, -10
%sel = select i1 %cmp, i32 %sub, i32 0
=>
%sel = usub_sat %a, 10
Done: 1
Optimization is correct!
----------------------------------------
Optimization: Backwards
Precondition: true
%cmp = icmp ult i32 %a, 2
%sub = add i32 %a, -2
%sel = select i1 %cmp, i32 %sub, i32 0
=>
%x = usub_sat 2, %a
%sel = sub 0, %x
Done: 1
Optimization is correct!
https://reviews.llvm.org/D69514
Files:
llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
llvm/test/Transforms/InstCombine/unsigned_saturated_sub.ll
Index: llvm/test/Transforms/InstCombine/unsigned_saturated_sub.ll
===================================================================
--- llvm/test/Transforms/InstCombine/unsigned_saturated_sub.ll
+++ llvm/test/Transforms/InstCombine/unsigned_saturated_sub.ll
@@ -160,10 +160,8 @@
define i32 @max_sub_ugt_c1(i32 %a) {
; CHECK-LABEL: @max_sub_ugt_c1(
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 1
-; CHECK-NEXT: [[SUB:%.*]] = add i32 [[A]], -1
-; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 0
-; CHECK-NEXT: ret i32 [[SEL]]
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A:%.*]], i32 1)
+; CHECK-NEXT: ret i32 [[TMP1]]
;
%cmp = icmp ugt i32 %a, 1
%sub = add i32 %a, -1
@@ -173,10 +171,8 @@
define i32 @max_sub_ugt_c10(i32 %a) {
; CHECK-LABEL: @max_sub_ugt_c10(
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 10
-; CHECK-NEXT: [[SUB:%.*]] = add i32 [[A]], -10
-; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 0
-; CHECK-NEXT: ret i32 [[SEL]]
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A:%.*]], i32 10)
+; CHECK-NEXT: ret i32 [[TMP1]]
;
%cmp = icmp ugt i32 %a, 10
%sub = add i32 %a, -10
@@ -211,10 +207,9 @@
define i32 @max_sub_ult_c2(i32 %a) {
; CHECK-LABEL: @max_sub_ult_c2(
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 2
-; CHECK-NEXT: [[SUB:%.*]] = add i32 [[A]], -2
-; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 0
-; CHECK-NEXT: ret i32 [[SEL]]
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 2, i32 [[A:%.*]])
+; CHECK-NEXT: [[TMP2:%.*]] = sub nsw i32 0, [[TMP1]]
+; CHECK-NEXT: ret i32 [[TMP2]]
;
%cmp = icmp ult i32 %a, 2
%sub = add i32 %a, -2
Index: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -705,10 +705,16 @@
"Unexpected isUnsigned predicate!");
// Account for swapped form of subtraction: ((a > b) ? b - a : 0).
+ // Checking for both a-b and a+(-b) as a constant.
bool IsNegative = false;
- if (match(TrueVal, m_Sub(m_Specific(B), m_Specific(A))))
+ const APInt *C;
+ if (match(TrueVal, m_Sub(m_Specific(B), m_Specific(A))) ||
+ (match(A, m_APInt(C)) &&
+ match(TrueVal, m_Add(m_Specific(B), m_SpecificInt(-*C)))))
IsNegative = true;
- else if (!match(TrueVal, m_Sub(m_Specific(A), m_Specific(B))))
+ else if (!match(TrueVal, m_Sub(m_Specific(A), m_Specific(B))) &&
+ !(match(B, m_APInt(C)) &&
+ match(TrueVal, m_Add(m_Specific(A), m_SpecificInt(-*C)))))
return nullptr;
// If sub is used anywhere else, we wouldn't be able to eliminate it
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D69514.226670.patch
Type: text/x-patch
Size: 2842 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20191028/23a0f7a8/attachment.bin>
More information about the llvm-commits
mailing list