[llvm] r347772 - [InstCombine] Canonicalize ssub.sat to sadd.sat
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 28 08:37:10 PST 2018
Author: nikic
Date: Wed Nov 28 08:37:09 2018
New Revision: 347772
URL: http://llvm.org/viewvc/llvm-project?rev=347772&view=rev
Log:
[InstCombine] Canonicalize ssub.sat to sadd.sat
Canonicalize ssub.sat(X, C) to ssub.sat(X, -C) if C is constant and
not signed minimum. This will help further optimizations to apply.
This change is part of https://reviews.llvm.org/D54534.
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
llvm/trunk/test/Transforms/InstCombine/saturating-add-sub.ll
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=347772&r1=347771&r2=347772&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Wed Nov 28 08:37:09 2018
@@ -2102,6 +2102,17 @@ Instruction *InstCombiner::visitCallInst
return BinaryOperator::CreateNSWSub(Arg0, Arg1);
break;
}
+
+ // ssub.sat(X, C) -> sadd.sat(X, -C) if C != MIN
+ // TODO: Support non-splat C.
+ const APInt *C;
+ if (IID == Intrinsic::ssub_sat && match(Arg1, m_APInt(C)) &&
+ !C->isMinSignedValue()) {
+ Value *NegVal = ConstantInt::get(II->getType(), -*C);
+ return replaceInstUsesWith(
+ *II, Builder.CreateBinaryIntrinsic(
+ Intrinsic::sadd_sat, Arg0, NegVal));
+ }
break;
}
Modified: llvm/trunk/test/Transforms/InstCombine/saturating-add-sub.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/saturating-add-sub.ll?rev=347772&r1=347771&r2=347772&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/saturating-add-sub.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/saturating-add-sub.ll Wed Nov 28 08:37:09 2018
@@ -331,8 +331,8 @@ define i8 @test_scalar_usub_canonical(i8
; Canonicalize ssub to sadd.
define i8 @test_scalar_ssub_canonical(i8 %a) {
; CHECK-LABEL: @test_scalar_ssub_canonical(
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[A:%.*]], i8 10)
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A:%.*]], i8 -10)
+; CHECK-NEXT: ret i8 [[TMP1]]
;
%r = call i8 @llvm.ssub.sat.i8(i8 %a, i8 10)
ret i8 %r
@@ -340,8 +340,8 @@ define i8 @test_scalar_ssub_canonical(i8
define <2 x i8> @test_vector_ssub_canonical(<2 x i8> %a) {
; CHECK-LABEL: @test_vector_ssub_canonical(
-; CHECK-NEXT: [[R:%.*]] = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> <i8 10, i8 10>)
-; CHECK-NEXT: ret <2 x i8> [[R]]
+; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> <i8 -10, i8 -10>)
+; CHECK-NEXT: ret <2 x i8> [[TMP1]]
;
%r = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 10, i8 10>)
ret <2 x i8> %r
@@ -437,9 +437,9 @@ define <2 x i8> @test_vector_usub_overfl
; Can combine ssubs if sign matches.
define i8 @test_scalar_ssub_both_positive(i8 %a) {
; CHECK-LABEL: @test_scalar_ssub_both_positive(
-; CHECK-NEXT: [[Z1:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[A:%.*]], i8 10)
-; CHECK-NEXT: [[Z2:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[Z1]], i8 20)
-; CHECK-NEXT: ret i8 [[Z2]]
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A:%.*]], i8 -10)
+; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[TMP1]], i8 -20)
+; CHECK-NEXT: ret i8 [[TMP2]]
;
%z1 = call i8 @llvm.ssub.sat.i8(i8 %a, i8 10)
%z2 = call i8 @llvm.ssub.sat.i8(i8 %z1, i8 20)
@@ -448,9 +448,9 @@ define i8 @test_scalar_ssub_both_positiv
define <2 x i8> @test_vector_ssub_both_positive(<2 x i8> %a) {
; CHECK-LABEL: @test_vector_ssub_both_positive(
-; CHECK-NEXT: [[Z1:%.*]] = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> <i8 10, i8 10>)
-; CHECK-NEXT: [[Z2:%.*]] = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> [[Z1]], <2 x i8> <i8 20, i8 20>)
-; CHECK-NEXT: ret <2 x i8> [[Z2]]
+; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> <i8 -10, i8 -10>)
+; CHECK-NEXT: [[TMP2:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> [[TMP1]], <2 x i8> <i8 -20, i8 -20>)
+; CHECK-NEXT: ret <2 x i8> [[TMP2]]
;
%z1 = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 10, i8 10>)
%z2 = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %z1, <2 x i8> <i8 20, i8 20>)
@@ -459,9 +459,9 @@ define <2 x i8> @test_vector_ssub_both_p
define i8 @test_scalar_ssub_both_negative(i8 %a) {
; CHECK-LABEL: @test_scalar_ssub_both_negative(
-; CHECK-NEXT: [[U1:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[A:%.*]], i8 -10)
-; CHECK-NEXT: [[U2:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[U1]], i8 -20)
-; CHECK-NEXT: ret i8 [[U2]]
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A:%.*]], i8 10)
+; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[TMP1]], i8 20)
+; CHECK-NEXT: ret i8 [[TMP2]]
;
%u1 = call i8 @llvm.ssub.sat.i8(i8 %a, i8 -10)
%u2 = call i8 @llvm.ssub.sat.i8(i8 %u1, i8 -20)
@@ -470,9 +470,9 @@ define i8 @test_scalar_ssub_both_negativ
define <2 x i8> @test_vector_ssub_both_negative(<2 x i8> %a) {
; CHECK-LABEL: @test_vector_ssub_both_negative(
-; CHECK-NEXT: [[U1:%.*]] = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> <i8 -10, i8 -10>)
-; CHECK-NEXT: [[U2:%.*]] = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> [[U1]], <2 x i8> <i8 -20, i8 -20>)
-; CHECK-NEXT: ret <2 x i8> [[U2]]
+; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> <i8 10, i8 10>)
+; CHECK-NEXT: [[TMP2:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> [[TMP1]], <2 x i8> <i8 20, i8 20>)
+; CHECK-NEXT: ret <2 x i8> [[TMP2]]
;
%u1 = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %a, <2 x i8> <i8 -10, i8 -10>)
%u2 = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %u1, <2 x i8> <i8 -20, i8 -20>)
@@ -482,9 +482,9 @@ define <2 x i8> @test_vector_ssub_both_n
; Can't combine ssubs if constants have different sign.
define i8 @test_scalar_ssub_different_sign(i8 %a) {
; CHECK-LABEL: @test_scalar_ssub_different_sign(
-; CHECK-NEXT: [[V1:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[A:%.*]], i8 10)
-; CHECK-NEXT: [[V2:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[V1]], i8 -20)
-; CHECK-NEXT: ret i8 [[V2]]
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A:%.*]], i8 -10)
+; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[TMP1]], i8 20)
+; CHECK-NEXT: ret i8 [[TMP2]]
;
%v1 = call i8 @llvm.ssub.sat.i8(i8 %a, i8 10)
%v2 = call i8 @llvm.ssub.sat.i8(i8 %v1, i8 -20)
@@ -495,8 +495,8 @@ define i8 @test_scalar_ssub_different_si
define i8 @test_scalar_sadd_ssub(i8 %a) {
; CHECK-LABEL: @test_scalar_sadd_ssub(
; CHECK-NEXT: [[V1:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A:%.*]], i8 10)
-; CHECK-NEXT: [[V2:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[V1]], i8 -20)
-; CHECK-NEXT: ret i8 [[V2]]
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[V1]], i8 20)
+; CHECK-NEXT: ret i8 [[TMP1]]
;
%v1 = call i8 @llvm.sadd.sat.i8(i8 10, i8 %a)
%v2 = call i8 @llvm.ssub.sat.i8(i8 %v1, i8 -20)
@@ -506,8 +506,8 @@ define i8 @test_scalar_sadd_ssub(i8 %a)
define <2 x i8> @test_vector_sadd_ssub(<2 x i8> %a) {
; CHECK-LABEL: @test_vector_sadd_ssub(
; CHECK-NEXT: [[V1:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> <i8 -10, i8 -10>)
-; CHECK-NEXT: [[V2:%.*]] = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> [[V1]], <2 x i8> <i8 20, i8 20>)
-; CHECK-NEXT: ret <2 x i8> [[V2]]
+; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> [[V1]], <2 x i8> <i8 -20, i8 -20>)
+; CHECK-NEXT: ret <2 x i8> [[TMP1]]
;
%v1 = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> <i8 -10, i8 -10>, <2 x i8> %a)
%v2 = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %v1, <2 x i8> <i8 20, i8 20>)
@@ -517,9 +517,9 @@ define <2 x i8> @test_vector_sadd_ssub(<
; Can't combine ssubs if they overflow.
define i8 @test_scalar_ssub_overflow(i8 %a) {
; CHECK-LABEL: @test_scalar_ssub_overflow(
-; CHECK-NEXT: [[W1:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[A:%.*]], i8 100)
-; CHECK-NEXT: [[W2:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[W1]], i8 100)
-; CHECK-NEXT: ret i8 [[W2]]
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A:%.*]], i8 -100)
+; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[TMP1]], i8 -100)
+; CHECK-NEXT: ret i8 [[TMP2]]
;
%w1 = call i8 @llvm.ssub.sat.i8(i8 %a, i8 100)
%w2 = call i8 @llvm.ssub.sat.i8(i8 %w1, i8 100)
@@ -641,8 +641,8 @@ define <2 x i8> @test_vector_ssub_nneg_n
define i8 @test_scalar_ssub_neg_nneg(i8 %a) {
; CHECK-LABEL: @test_scalar_ssub_neg_nneg(
; CHECK-NEXT: [[A_NEG:%.*]] = or i8 [[A:%.*]], -128
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[A_NEG]], i8 10)
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[A_NEG]], i8 -10)
+; CHECK-NEXT: ret i8 [[TMP1]]
;
%a_neg = or i8 %a, -128
%r = call i8 @llvm.ssub.sat.i8(i8 %a_neg, i8 10)
More information about the llvm-commits
mailing list