[Analysis] propagate poison through integer min/max intrinsics
authorSanjay Patel <spatel@rotateright.com>
Tue, 15 Feb 2022 15:09:36 +0000 (10:09 -0500)
committerSanjay Patel <spatel@rotateright.com>
Tue, 15 Feb 2022 15:45:32 +0000 (10:45 -0500)
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.

llvm/lib/Analysis/ConstantFolding.cpp
llvm/test/Transforms/InstSimplify/ConstProp/min-max.ll

index a21d3ce..b5169e5 100644 (file)
@@ -2506,6 +2506,11 @@ static Constant *ConstantFoldScalarCall2(StringRef Name,
     case Intrinsic::smin:
     case Intrinsic::umax:
     case Intrinsic::umin:
+      // 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)
index 6196333..a5f5d4e 100644 (file)
@@ -291,7 +291,7 @@ define i8 @smax() {
 
 define <5 x i8> @smax_vec() {
 ; CHECK-LABEL: @smax_vec(
-; CHECK-NEXT:    ret <5 x i8> <i8 undef, i8 127, i8 127, i8 42, i8 127>
+; CHECK-NEXT:    ret <5 x i8> <i8 poison, i8 127, i8 poison, i8 42, i8 127>
 ;
   %r = call <5 x i8> @llvm.smax.v5i8(<5 x i8> <i8 poison, i8 undef, i8 1, i8 42, i8 42>, <5 x i8> <i8 undef, i8 1, i8 poison, i8 42, i8 127>)
   ret <5 x i8> %r
@@ -307,7 +307,7 @@ define i8 @smin() {
 
 define <5 x i8> @smin_vec() {
 ; CHECK-LABEL: @smin_vec(
-; CHECK-NEXT:    ret <5 x i8> <i8 undef, i8 -128, i8 -128, i8 42, i8 -127>
+; CHECK-NEXT:    ret <5 x i8> <i8 poison, i8 -128, i8 poison, i8 42, i8 -127>
 ;
   %r = call <5 x i8> @llvm.smin.v5i8(<5 x i8> <i8 poison, i8 undef, i8 1, i8 42, i8 42>, <5 x i8> <i8 undef, i8 1, i8 poison, i8 42, i8 129>)
   ret <5 x i8> %r
@@ -323,7 +323,7 @@ define i8 @umax() {
 
 define <5 x i8> @umax_vec() {
 ; CHECK-LABEL: @umax_vec(
-; CHECK-NEXT:    ret <5 x i8> <i8 undef, i8 -1, i8 -1, i8 42, i8 -128>
+; CHECK-NEXT:    ret <5 x i8> <i8 poison, i8 -1, i8 poison, i8 42, i8 -128>
 ;
   %r = call <5 x i8> @llvm.umax.v5i8(<5 x i8> <i8 poison, i8 undef, i8 1, i8 42, i8 42>, <5 x i8> <i8 undef, i8 1, i8 poison, i8 42, i8 128>)
   ret <5 x i8> %r
@@ -339,7 +339,7 @@ define i8 @umin() {
 
 define <5 x i8> @umin_vec() {
 ; CHECK-LABEL: @umin_vec(
-; CHECK-NEXT:    ret <5 x i8> <i8 undef, i8 0, i8 0, i8 42, i8 42>
+; CHECK-NEXT:    ret <5 x i8> <i8 poison, i8 0, i8 poison, i8 42, i8 42>
 ;
   %r = call <5 x i8> @llvm.umin.v5i8(<5 x i8> <i8 poison, i8 undef, i8 1, i8 42, i8 42>, <5 x i8> <i8 undef, i8 1, i8 poison, i8 42, i8 128>)
   ret <5 x i8> %r