[llvm] 7cc0a29 - [Analysis] propagate poison through add/sub saturate intrinsics

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 15 07:47:09 PST 2022


Author: Sanjay Patel
Date: 2022-02-15T10:45:32-05:00
New Revision: 7cc0a29b3ffa2d89b4d1c2f8f52b8c393b0d41da

URL: https://github.com/llvm/llvm-project/commit/7cc0a29b3ffa2d89b4d1c2f8f52b8c393b0d41da
DIFF: https://github.com/llvm/llvm-project/commit/7cc0a29b3ffa2d89b4d1c2f8f52b8c393b0d41da.diff

LOG: [Analysis] propagate poison through add/sub saturate intrinsics

A more general enhancement needs to add tests and make sure
that intrinsics that return structs are correct. There are also
target-specific intrinsics, and I'm not sure what behavior is
expected for those.

Added: 
    

Modified: 
    llvm/lib/Analysis/ConstantFolding.cpp
    llvm/test/Transforms/InstSimplify/ConstProp/saturating-add-sub.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index b5169e540df7..fff46bfff5d2 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -2577,6 +2577,11 @@ static Constant *ConstantFoldScalarCall2(StringRef Name,
     }
     case Intrinsic::uadd_sat:
     case Intrinsic::sadd_sat:
+      // This is the same as for binary ops - poison propagates.
+      // TODO: Poison handling should be consolidated.
+      if (isa<PoisonValue>(Operands[0]) || isa<PoisonValue>(Operands[1]))
+        return PoisonValue::get(Ty);
+
       if (!C0 && !C1)
         return UndefValue::get(Ty);
       if (!C0 || !C1)
@@ -2587,6 +2592,11 @@ static Constant *ConstantFoldScalarCall2(StringRef Name,
         return ConstantInt::get(Ty, C0->sadd_sat(*C1));
     case Intrinsic::usub_sat:
     case Intrinsic::ssub_sat:
+      // This is the same as for binary ops - poison propagates.
+      // TODO: Poison handling should be consolidated.
+      if (isa<PoisonValue>(Operands[0]) || isa<PoisonValue>(Operands[1]))
+        return PoisonValue::get(Ty);
+
       if (!C0 && !C1)
         return UndefValue::get(Ty);
       if (!C0 || !C1)

diff  --git a/llvm/test/Transforms/InstSimplify/ConstProp/saturating-add-sub.ll b/llvm/test/Transforms/InstSimplify/ConstProp/saturating-add-sub.ll
index a6e6373a0649..deeb238bdd0e 100644
--- a/llvm/test/Transforms/InstSimplify/ConstProp/saturating-add-sub.ll
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/saturating-add-sub.ll
@@ -369,7 +369,7 @@ define <2 x i8> @test_ssub_vector_op1_undef_mix2() {
 
 define i8 @test_uadd_scalar_both_poison() {
 ; CHECK-LABEL: @test_uadd_scalar_both_poison(
-; CHECK-NEXT:    ret i8 undef
+; CHECK-NEXT:    ret i8 poison
 ;
   %x = call i8 @llvm.uadd.sat.i8(i8 poison, i8 poison)
   ret i8 %x
@@ -377,7 +377,7 @@ define i8 @test_uadd_scalar_both_poison() {
 
 define i8 @test_sadd_scalar_both_poison() {
 ; CHECK-LABEL: @test_sadd_scalar_both_poison(
-; CHECK-NEXT:    ret i8 undef
+; CHECK-NEXT:    ret i8 poison
 ;
   %x = call i8 @llvm.sadd.sat.i8(i8 poison, i8 poison)
   ret i8 %x
@@ -385,7 +385,7 @@ define i8 @test_sadd_scalar_both_poison() {
 
 define i8 @test_usub_scalar_both_poison() {
 ; CHECK-LABEL: @test_usub_scalar_both_poison(
-; CHECK-NEXT:    ret i8 undef
+; CHECK-NEXT:    ret i8 poison
 ;
   %x = call i8 @llvm.usub.sat.i8(i8 poison, i8 poison)
   ret i8 %x
@@ -393,7 +393,7 @@ define i8 @test_usub_scalar_both_poison() {
 
 define i8 @test_ssub_scalar_both_poison() {
 ; CHECK-LABEL: @test_ssub_scalar_both_poison(
-; CHECK-NEXT:    ret i8 undef
+; CHECK-NEXT:    ret i8 poison
 ;
   %x = call i8 @llvm.ssub.sat.i8(i8 poison, i8 poison)
   ret i8 %x
@@ -401,7 +401,7 @@ define i8 @test_ssub_scalar_both_poison() {
 
 define i8 @test_uadd_scalar_op2_poison() {
 ; CHECK-LABEL: @test_uadd_scalar_op2_poison(
-; CHECK-NEXT:    ret i8 -1
+; CHECK-NEXT:    ret i8 poison
 ;
   %x = call i8 @llvm.uadd.sat.i8(i8 10, i8 poison)
   ret i8 %x
@@ -409,7 +409,7 @@ define i8 @test_uadd_scalar_op2_poison() {
 
 define i8 @test_sadd_scalar_op1_poison() {
 ; CHECK-LABEL: @test_sadd_scalar_op1_poison(
-; CHECK-NEXT:    ret i8 -1
+; CHECK-NEXT:    ret i8 poison
 ;
   %x = call i8 @llvm.sadd.sat.i8(i8 poison, i8 10)
   ret i8 %x
@@ -417,7 +417,7 @@ define i8 @test_sadd_scalar_op1_poison() {
 
 define i8 @test_usub_scalar_op2_poison() {
 ; CHECK-LABEL: @test_usub_scalar_op2_poison(
-; CHECK-NEXT:    ret i8 0
+; CHECK-NEXT:    ret i8 poison
 ;
   %x = call i8 @llvm.usub.sat.i8(i8 10, i8 poison)
   ret i8 %x
@@ -425,7 +425,7 @@ define i8 @test_usub_scalar_op2_poison() {
 
 define i8 @test_usub_scalar_op1_poison() {
 ; CHECK-LABEL: @test_usub_scalar_op1_poison(
-; CHECK-NEXT:    ret i8 0
+; CHECK-NEXT:    ret i8 poison
 ;
   %x = call i8 @llvm.usub.sat.i8(i8 poison, i8 10)
   ret i8 %x
@@ -433,7 +433,7 @@ define i8 @test_usub_scalar_op1_poison() {
 
 define <2 x i8> @test_uadd_vector_both_poison_splat() {
 ; CHECK-LABEL: @test_uadd_vector_both_poison_splat(
-; CHECK-NEXT:    ret <2 x i8> undef
+; CHECK-NEXT:    ret <2 x i8> poison
 ;
   %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> poison, <2 x i8> poison)
   ret <2 x i8> %x
@@ -441,7 +441,7 @@ define <2 x i8> @test_uadd_vector_both_poison_splat() {
 
 define <2 x i8> @test_sadd_vector_both_poison_splat() {
 ; CHECK-LABEL: @test_sadd_vector_both_poison_splat(
-; CHECK-NEXT:    ret <2 x i8> undef
+; CHECK-NEXT:    ret <2 x i8> poison
 ;
   %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> poison, <2 x i8> poison)
   ret <2 x i8> %x
@@ -449,7 +449,7 @@ define <2 x i8> @test_sadd_vector_both_poison_splat() {
 
 define <2 x i8> @test_usub_vector_both_poison_splat() {
 ; CHECK-LABEL: @test_usub_vector_both_poison_splat(
-; CHECK-NEXT:    ret <2 x i8> undef
+; CHECK-NEXT:    ret <2 x i8> poison
 ;
   %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> poison, <2 x i8> poison)
   ret <2 x i8> %x
@@ -457,7 +457,7 @@ define <2 x i8> @test_usub_vector_both_poison_splat() {
 
 define <2 x i8> @test_ssub_vector_both_poison_splat() {
 ; CHECK-LABEL: @test_ssub_vector_both_poison_splat(
-; CHECK-NEXT:    ret <2 x i8> undef
+; CHECK-NEXT:    ret <2 x i8> poison
 ;
   %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> poison, <2 x i8> poison)
   ret <2 x i8> %x
@@ -465,7 +465,7 @@ define <2 x i8> @test_ssub_vector_both_poison_splat() {
 
 define <2 x i8> @test_uadd_vector_op2_poison_splat() {
 ; CHECK-LABEL: @test_uadd_vector_op2_poison_splat(
-; CHECK-NEXT:    ret <2 x i8> <i8 -1, i8 -1>
+; CHECK-NEXT:    ret <2 x i8> poison
 ;
   %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> <i8 10, i8 20>, <2 x i8> poison)
   ret <2 x i8> %x
@@ -473,7 +473,7 @@ define <2 x i8> @test_uadd_vector_op2_poison_splat() {
 
 define <2 x i8> @test_sadd_vector_op1_poison_splat() {
 ; CHECK-LABEL: @test_sadd_vector_op1_poison_splat(
-; CHECK-NEXT:    ret <2 x i8> <i8 -1, i8 -1>
+; CHECK-NEXT:    ret <2 x i8> poison
 ;
   %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> poison, <2 x i8> <i8 10, i8 20>)
   ret <2 x i8> %x
@@ -481,7 +481,7 @@ define <2 x i8> @test_sadd_vector_op1_poison_splat() {
 
 define <2 x i8> @test_usub_vector_op2_poison_splat() {
 ; CHECK-LABEL: @test_usub_vector_op2_poison_splat(
-; CHECK-NEXT:    ret <2 x i8> zeroinitializer
+; CHECK-NEXT:    ret <2 x i8> poison
 ;
   %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 10, i8 20>, <2 x i8> poison)
   ret <2 x i8> %x
@@ -489,7 +489,7 @@ define <2 x i8> @test_usub_vector_op2_poison_splat() {
 
 define <2 x i8> @test_ssub_vector_op1_poison_splat() {
 ; CHECK-LABEL: @test_ssub_vector_op1_poison_splat(
-; CHECK-NEXT:    ret <2 x i8> zeroinitializer
+; CHECK-NEXT:    ret <2 x i8> poison
 ;
   %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> poison, <2 x i8> <i8 10, i8 20>)
   ret <2 x i8> %x
@@ -497,7 +497,7 @@ define <2 x i8> @test_ssub_vector_op1_poison_splat() {
 
 define <2 x i8> @test_uadd_vector_op2_poison_mix1() {
 ; CHECK-LABEL: @test_uadd_vector_op2_poison_mix1(
-; CHECK-NEXT:    ret <2 x i8> <i8 30, i8 undef>
+; CHECK-NEXT:    ret <2 x i8> <i8 30, i8 poison>
 ;
   %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> <i8 10, i8 poison>, <2 x i8> <i8 20, i8 poison>)
   ret <2 x i8> %x
@@ -505,7 +505,7 @@ define <2 x i8> @test_uadd_vector_op2_poison_mix1() {
 
 define <2 x i8> @test_uadd_vector_op2_poison_mix2() {
 ; CHECK-LABEL: @test_uadd_vector_op2_poison_mix2(
-; CHECK-NEXT:    ret <2 x i8> <i8 -1, i8 -1>
+; CHECK-NEXT:    ret <2 x i8> poison
 ;
   %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> <i8 10, i8 poison>, <2 x i8> <i8 poison, i8 20>)
   ret <2 x i8> %x
@@ -513,7 +513,7 @@ define <2 x i8> @test_uadd_vector_op2_poison_mix2() {
 
 define <2 x i8> @test_sadd_vector_op1_poison_mix1() {
 ; CHECK-LABEL: @test_sadd_vector_op1_poison_mix1(
-; CHECK-NEXT:    ret <2 x i8> <i8 undef, i8 30>
+; CHECK-NEXT:    ret <2 x i8> <i8 poison, i8 30>
 ;
   %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> <i8 poison, i8 10>, <2 x i8> <i8 poison, i8 20>)
   ret <2 x i8> %x
@@ -521,7 +521,7 @@ define <2 x i8> @test_sadd_vector_op1_poison_mix1() {
 
 define <2 x i8> @test_sadd_vector_op1_poison_mix2() {
 ; CHECK-LABEL: @test_sadd_vector_op1_poison_mix2(
-; CHECK-NEXT:    ret <2 x i8> <i8 -1, i8 -1>
+; CHECK-NEXT:    ret <2 x i8> poison
 ;
   %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> <i8 poison, i8 10>, <2 x i8> <i8 20, i8 poison>)
   ret <2 x i8> %x
@@ -529,7 +529,7 @@ define <2 x i8> @test_sadd_vector_op1_poison_mix2() {
 
 define <2 x i8> @test_usub_vector_op2_poison_mix1() {
 ; CHECK-LABEL: @test_usub_vector_op2_poison_mix1(
-; CHECK-NEXT:    ret <2 x i8> <i8 0, i8 undef>
+; CHECK-NEXT:    ret <2 x i8> <i8 0, i8 poison>
 ;
   %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 10, i8 poison>, <2 x i8> <i8 20, i8 poison>)
   ret <2 x i8> %x
@@ -537,7 +537,7 @@ define <2 x i8> @test_usub_vector_op2_poison_mix1() {
 
 define <2 x i8> @test_usub_vector_op2_poison_mix2() {
 ; CHECK-LABEL: @test_usub_vector_op2_poison_mix2(
-; CHECK-NEXT:    ret <2 x i8> zeroinitializer
+; CHECK-NEXT:    ret <2 x i8> poison
 ;
   %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 10, i8 poison>, <2 x i8> <i8 poison, i8 20>)
   ret <2 x i8> %x
@@ -545,7 +545,7 @@ define <2 x i8> @test_usub_vector_op2_poison_mix2() {
 
 define <2 x i8> @test_ssub_vector_op1_poison_mix1() {
 ; CHECK-LABEL: @test_ssub_vector_op1_poison_mix1(
-; CHECK-NEXT:    ret <2 x i8> <i8 undef, i8 -10>
+; CHECK-NEXT:    ret <2 x i8> <i8 poison, i8 -10>
 ;
   %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> <i8 poison, i8 10>, <2 x i8> <i8 poison, i8 20>)
   ret <2 x i8> %x
@@ -553,7 +553,7 @@ define <2 x i8> @test_ssub_vector_op1_poison_mix1() {
 
 define <2 x i8> @test_ssub_vector_op1_poison_mix2() {
 ; CHECK-LABEL: @test_ssub_vector_op1_poison_mix2(
-; CHECK-NEXT:    ret <2 x i8> zeroinitializer
+; CHECK-NEXT:    ret <2 x i8> poison
 ;
   %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> <i8 poison, i8 10>, <2 x i8> <i8 20, i8 poison>)
   ret <2 x i8> %x


        


More information about the llvm-commits mailing list