[llvm] 2e26633 - [IR] document and update ctlz/cttz intrinsics to optionally return poison rather than undef

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sun Jan 23 08:22:56 PST 2022


Author: Sanjay Patel
Date: 2022-01-23T11:22:48-05:00
New Revision: 2e26633af0c88ea23e3e8783ef60e621f282d3fb

URL: https://github.com/llvm/llvm-project/commit/2e26633af0c88ea23e3e8783ef60e621f282d3fb
DIFF: https://github.com/llvm/llvm-project/commit/2e26633af0c88ea23e3e8783ef60e621f282d3fb.diff

LOG: [IR] document and update ctlz/cttz intrinsics to optionally return poison rather than undef

The behavior in Analysis (knownbits) implements poison semantics already,
and we expect the transforms (for example, in instcombine) derived from
those semantics, so this patch changes the LangRef and remaining code to
be consistent. This is one more step in removing "undef" from LLVM.

Without this, I think https://github.com/llvm/llvm-project/issues/53330
has a legitimate complaint because that report wants to allow subsequent
code to mask off bits, and that is allowed with undef values. The clang
builtins are not actually documented anywhere AFAICT, but we might want
to add that to remove more uncertainty.

Differential Revision: https://reviews.llvm.org/D117912

Added: 
    

Modified: 
    llvm/docs/LangRef.rst
    llvm/lib/Analysis/ConstantFolding.cpp
    llvm/lib/Analysis/ValueTracking.cpp
    llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
    llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
    llvm/test/Transforms/InstCombine/intrinsic-select.ll
    llvm/test/Transforms/InstCombine/intrinsics.ll
    llvm/test/Transforms/InstSimplify/ConstProp/bitcount.ll

Removed: 
    


################################################################################
diff  --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index f748fc5d4d213..aa010193d114b 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -14958,12 +14958,8 @@ targets support all bit widths or vector types, however.
 
 ::
 
-      declare i8   @llvm.ctlz.i8  (i8   <src>, i1 <is_zero_undef>)
-      declare i16  @llvm.ctlz.i16 (i16  <src>, i1 <is_zero_undef>)
-      declare i32  @llvm.ctlz.i32 (i32  <src>, i1 <is_zero_undef>)
-      declare i64  @llvm.ctlz.i64 (i64  <src>, i1 <is_zero_undef>)
-      declare i256 @llvm.ctlz.i256(i256 <src>, i1 <is_zero_undef>)
-      declare <2 x i32> @llvm.ctlz.v2i32(<2 x i32> <src>, i1 <is_zero_undef>)
+      declare i8   @llvm.ctlz.i8  (i8   <src>, i1 <is_zero_poison>)
+      declare <2 x i37> @llvm.ctlz.v2i37(<2 x i37> <src>, i1 <is_zero_poison>)
 
 Overview:
 """""""""
@@ -14978,11 +14974,12 @@ The first argument is the value to be counted. This argument may be of
 any integer type, or a vector with integer element type. The return
 type must match the first argument type.
 
-The second argument must be a constant and is a flag to indicate whether
-the intrinsic should ensure that a zero as the first argument produces a
-defined result. Historically some architectures did not provide a
-defined result for zero values as efficiently, and many algorithms are
-now predicated on avoiding zero-value inputs.
+The second argument is a constant flag that indicates whether the intrinsic
+returns a valid result if the first argument is zero. If the first
+argument is zero and the second argument is true, the result is poison.
+Historically some architectures did not provide a defined result for zero
+values as efficiently, and many algorithms are now predicated on avoiding
+zero-value inputs.
 
 Semantics:
 """"""""""
@@ -14990,7 +14987,7 @@ Semantics:
 The '``llvm.ctlz``' intrinsic counts the leading (most significant)
 zeros in a variable, or within each element of the vector. If
 ``src == 0`` then the result is the size in bits of the type of ``src``
-if ``is_zero_undef == 0`` and ``undef`` otherwise. For example,
+if ``is_zero_poison == 0`` and ``poison`` otherwise. For example,
 ``llvm.ctlz(i32 2) = 30``.
 
 '``llvm.cttz.*``' Intrinsic
@@ -15005,12 +15002,8 @@ support all bit widths or vector types, however.
 
 ::
 
-      declare i8   @llvm.cttz.i8  (i8   <src>, i1 <is_zero_undef>)
-      declare i16  @llvm.cttz.i16 (i16  <src>, i1 <is_zero_undef>)
-      declare i32  @llvm.cttz.i32 (i32  <src>, i1 <is_zero_undef>)
-      declare i64  @llvm.cttz.i64 (i64  <src>, i1 <is_zero_undef>)
-      declare i256 @llvm.cttz.i256(i256 <src>, i1 <is_zero_undef>)
-      declare <2 x i32> @llvm.cttz.v2i32(<2 x i32> <src>, i1 <is_zero_undef>)
+      declare i42   @llvm.cttz.i42  (i42   <src>, i1 <is_zero_poison>)
+      declare <2 x i32> @llvm.cttz.v2i32(<2 x i32> <src>, i1 <is_zero_poison>)
 
 Overview:
 """""""""
@@ -15025,11 +15018,12 @@ The first argument is the value to be counted. This argument may be of
 any integer type, or a vector with integer element type. The return
 type must match the first argument type.
 
-The second argument must be a constant and is a flag to indicate whether
-the intrinsic should ensure that a zero as the first argument produces a
-defined result. Historically some architectures did not provide a
-defined result for zero values as efficiently, and many algorithms are
-now predicated on avoiding zero-value inputs.
+The second argument is a constant flag that indicates whether the intrinsic
+returns a valid result if the first argument is zero. If the first
+argument is zero and the second argument is true, the result is poison.
+Historically some architectures did not provide a defined result for zero
+values as efficiently, and many algorithms are now predicated on avoiding
+zero-value inputs.
 
 Semantics:
 """"""""""
@@ -15037,7 +15031,7 @@ Semantics:
 The '``llvm.cttz``' intrinsic counts the trailing (least significant)
 zeros in a variable, or within each element of a vector. If ``src == 0``
 then the result is the size in bits of the type of ``src`` if
-``is_zero_undef == 0`` and ``undef`` otherwise. For example,
+``is_zero_poison == 0`` and ``poison`` otherwise. For example,
 ``llvm.cttz(2) = 1``.
 
 .. _int_overflow:

diff  --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 38c9cc7b9df29..772316e7469d9 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -2572,9 +2572,9 @@ static Constant *ConstantFoldScalarCall2(StringRef Name,
     case Intrinsic::ctlz:
       assert(C1 && "Must be constant int");
 
-      // cttz(0, 1) and ctlz(0, 1) are undef.
+      // cttz(0, 1) and ctlz(0, 1) are poison.
       if (C1->isOne() && (!C0 || C0->isZero()))
-        return UndefValue::get(Ty);
+        return PoisonValue::get(Ty);
       if (!C0)
         return Constant::getNullValue(Ty);
       if (IntrinsicID == Intrinsic::cttz)

diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 942dbe043ab3f..34358739f9a85 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -1593,7 +1593,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
         computeKnownBits(I->getOperand(0), Known2, Depth + 1, Q);
         // If we have a known 1, its position is our upper bound.
         unsigned PossibleLZ = Known2.countMaxLeadingZeros();
-        // If this call is undefined for 0, the result will be less than 2^n.
+        // If this call is poison for 0 input, the result will be less than 2^n.
         if (II->getArgOperand(1) == ConstantInt::getTrue(II->getContext()))
           PossibleLZ = std::min(PossibleLZ, BitWidth - 1);
         unsigned LowBits = Log2_32(PossibleLZ)+1;
@@ -1604,7 +1604,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
         computeKnownBits(I->getOperand(0), Known2, Depth + 1, Q);
         // If we have a known 1, its position is our upper bound.
         unsigned PossibleTZ = Known2.countMaxTrailingZeros();
-        // If this call is undefined for 0, the result will be less than 2^n.
+        // If this call is poison for 0 input, the result will be less than 2^n.
         if (II->getArgOperand(1) == ConstantInt::getTrue(II->getContext()))
           PossibleTZ = std::min(PossibleTZ, BitWidth - 1);
         unsigned LowBits = Log2_32(PossibleTZ)+1;

diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index f63a186166ecc..3a3f169d2f516 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -494,7 +494,7 @@ static Instruction *foldCttzCtlz(IntrinsicInst &II, InstCombinerImpl &IC) {
     // ctlz/cttz i1 Op0 --> not Op0
     if (match(Op1, m_Zero()))
       return BinaryOperator::CreateNot(Op0);
-    // If zero is undef, then the input can be assumed to be "true", so the
+    // If zero is poison, then the input can be assumed to be "true", so the
     // instruction simplifies to "false".
     assert(match(Op1, m_One()) && "Expected ctlz/cttz operand to be 0 or 1");
     return IC.replaceInstUsesWith(II, ConstantInt::getNullValue(II.getType()));
@@ -519,7 +519,7 @@ static Instruction *foldCttzCtlz(IntrinsicInst &II, InstCombinerImpl &IC) {
     }
 
     // Zext doesn't change the number of trailing zeros, so narrow:
-    // cttz(zext(x)) -> zext(cttz(x)) if the 'ZeroIsUndef' parameter is 'true'.
+    // cttz(zext(x)) -> zext(cttz(x)) if the 'ZeroIsPoison' parameter is 'true'.
     if (match(Op0, m_OneUse(m_ZExt(m_Value(X)))) && match(Op1, m_One())) {
       auto *Cttz = IC.Builder.CreateBinaryIntrinsic(Intrinsic::cttz, X,
                                                     IC.Builder.getTrue());
@@ -556,7 +556,7 @@ static Instruction *foldCttzCtlz(IntrinsicInst &II, InstCombinerImpl &IC) {
   }
 
   // If the input to cttz/ctlz is known to be non-zero,
-  // then change the 'ZeroIsUndef' parameter to 'true'
+  // then change the 'ZeroIsPoison' parameter to 'true'
   // because we know the zero behavior can't affect the result.
   if (!Known.One.isZero() ||
       isKnownNonZero(Op0, IC.getDataLayout(), 0, &IC.getAssumptionCache(), &II,

diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index cbdf04572042c..65e60498ff954 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -943,7 +943,7 @@ static Instruction *foldSelectCtlzToCttz(ICmpInst *ICI, Value *TrueVal,
 }
 
 /// Attempt to fold a cttz/ctlz followed by a icmp plus select into a single
-/// call to cttz/ctlz with flag 'is_zero_undef' cleared.
+/// call to cttz/ctlz with flag 'is_zero_poison' cleared.
 ///
 /// For example, we can fold the following code sequence:
 /// \code
@@ -987,7 +987,7 @@ static Value *foldSelectCttzCtlz(ICmpInst *ICI, Value *TrueVal, Value *FalseVal,
   // sizeof in bits of 'Count'.
   unsigned SizeOfInBits = Count->getType()->getScalarSizeInBits();
   if (match(ValueOnZero, m_SpecificInt(SizeOfInBits))) {
-    // Explicitly clear the 'undef_on_zero' flag. It's always valid to go from
+    // Explicitly clear the 'is_zero_poison' flag. It's always valid to go from
     // true to false on this flag, so we can replace it for all users.
     II->setArgOperand(1, ConstantInt::getFalse(II->getContext()));
     return SelectArg;
@@ -995,7 +995,7 @@ static Value *foldSelectCttzCtlz(ICmpInst *ICI, Value *TrueVal, Value *FalseVal,
 
   // The ValueOnZero is not the bitwidth. But if the cttz/ctlz (and optional
   // zext/trunc) have one use (ending at the select), the cttz/ctlz result will
-  // not be used if the input is zero. Relax to 'undef_on_zero' for that case.
+  // not be used if the input is zero. Relax to 'zero is poison' for that case.
   if (II->hasOneUse() && SelectArg->hasOneUse() &&
       !match(II->getArgOperand(1), m_One()))
     II->setArgOperand(1, ConstantInt::getTrue(II->getContext()));

diff  --git a/llvm/test/Transforms/InstCombine/intrinsic-select.ll b/llvm/test/Transforms/InstCombine/intrinsic-select.ll
index 92c5e3b38bd76..cbabbb8b4456f 100644
--- a/llvm/test/Transforms/InstCombine/intrinsic-select.ll
+++ b/llvm/test/Transforms/InstCombine/intrinsic-select.ll
@@ -36,7 +36,7 @@ define i32 @ctlz_sel_const_true(i1 %b, i32 %x) {
 define <3 x i17> @ctlz_sel_const_false(<3 x i1> %b, <3 x i17> %x) {
 ; CHECK-LABEL: @ctlz_sel_const_false(
 ; CHECK-NEXT:    [[TMP1:%.*]] = call <3 x i17> @llvm.ctlz.v3i17(<3 x i17> [[X:%.*]], i1 true)
-; CHECK-NEXT:    [[C:%.*]] = select <3 x i1> [[B:%.*]], <3 x i17> [[TMP1]], <3 x i17> <i17 14, i17 0, i17 undef>
+; CHECK-NEXT:    [[C:%.*]] = select <3 x i1> [[B:%.*]], <3 x i17> [[TMP1]], <3 x i17> <i17 14, i17 0, i17 poison>
 ; CHECK-NEXT:    ret <3 x i17> [[C]]
 ;
   %s = select <3 x i1> %b, <3 x i17> %x, <3 x i17> <i17 7, i17 -1, i17 0>

diff  --git a/llvm/test/Transforms/InstCombine/intrinsics.ll b/llvm/test/Transforms/InstCombine/intrinsics.ll
index cabd82c3044eb..fc1c1e5aed3a7 100644
--- a/llvm/test/Transforms/InstCombine/intrinsics.ll
+++ b/llvm/test/Transforms/InstCombine/intrinsics.ll
@@ -79,8 +79,8 @@ define i1 @cttz_i1(i1 %arg) {
   ret i1 %cnt
 }
 
-define i1 @cttz_i1_zero_is_undef(i1 %arg) {
-; CHECK-LABEL: @cttz_i1_zero_is_undef(
+define i1 @cttz_i1_zero_is_poison(i1 %arg) {
+; CHECK-LABEL: @cttz_i1_zero_is_poison(
 ; CHECK-NEXT:    ret i1 false
 ;
   %cnt = call i1 @llvm.cttz.i1(i1 %arg, i1 true) nounwind readnone
@@ -96,8 +96,8 @@ define <2 x i1> @cttz_v2i1(<2 x i1> %arg) {
   ret <2 x i1> %cnt
 }
 
-define <2 x i1> @cttz_v2i1_zero_is_undef(<2 x i1> %arg) {
-; CHECK-LABEL: @cttz_v2i1_zero_is_undef(
+define <2 x i1> @cttz_v2i1_zero_is_poison(<2 x i1> %arg) {
+; CHECK-LABEL: @cttz_v2i1_zero_is_poison(
 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
 ;
   %cnt = call <2 x i1> @llvm.cttz.v2i1(<2 x i1> %arg, i1 true) nounwind readnone
@@ -196,8 +196,8 @@ define i1 @ctlz_i1(i1 %arg) {
   ret i1 %cnt
 }
 
-define i1 @ctlz_i1_zero_is_undef(i1 %arg) {
-; CHECK-LABEL: @ctlz_i1_zero_is_undef(
+define i1 @ctlz_i1_zero_is_poison(i1 %arg) {
+; CHECK-LABEL: @ctlz_i1_zero_is_poison(
 ; CHECK-NEXT:    ret i1 false
 ;
   %cnt = call i1 @llvm.ctlz.i1(i1 %arg, i1 true) nounwind readnone
@@ -213,8 +213,8 @@ define <2 x i1> @ctlz_v2i1(<2 x i1> %arg) {
   ret <2 x i1> %cnt
 }
 
-define <2 x i1> @ctlz_v2i1_zero_is_undef(<2 x i1> %arg) {
-; CHECK-LABEL: @ctlz_v2i1_zero_is_undef(
+define <2 x i1> @ctlz_v2i1_zero_is_poison(<2 x i1> %arg) {
+; CHECK-LABEL: @ctlz_v2i1_zero_is_poison(
 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
 ;
   %cnt = call <2 x i1> @llvm.ctlz.v2i1(<2 x i1> %arg, i1 true) nounwind readnone
@@ -283,24 +283,24 @@ define <2 x i1> @ctlz_knownbits3_vec(<2 x i8> %arg) {
   ret <2 x i1> %res
 }
 
-define i32 @ctlz_undef(i32 %Value) {
-; CHECK-LABEL: @ctlz_undef(
-; CHECK-NEXT:    ret i32 undef
+define i32 @ctlz_poison(i32 %Value) {
+; CHECK-LABEL: @ctlz_poison(
+; CHECK-NEXT:    ret i32 poison
 ;
   %ctlz = call i32 @llvm.ctlz.i32(i32 0, i1 true)
   ret i32 %ctlz
 }
 
-define <2 x i32> @ctlz_undef_vec(<2 x i32> %Value) {
-; CHECK-LABEL: @ctlz_undef_vec(
-; CHECK-NEXT:    ret <2 x i32> undef
+define <2 x i32> @ctlz_poison_vec(<2 x i32> %Value) {
+; CHECK-LABEL: @ctlz_poison_vec(
+; CHECK-NEXT:    ret <2 x i32> poison
 ;
   %ctlz = call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> zeroinitializer, i1 true)
   ret <2 x i32> %ctlz
 }
 
-define i32 @ctlz_make_undef(i32 %a) {
-; CHECK-LABEL: @ctlz_make_undef(
+define i32 @ctlz_no_zero(i32 %a) {
+; CHECK-LABEL: @ctlz_no_zero(
 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A:%.*]], 8
 ; CHECK-NEXT:    [[CTLZ:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[OR]], i1 true), !range [[RNG2:![0-9]+]]
 ; CHECK-NEXT:    ret i32 [[CTLZ]]
@@ -310,8 +310,8 @@ define i32 @ctlz_make_undef(i32 %a) {
   ret i32 %ctlz
 }
 
-define <2 x i32> @ctlz_make_undef_vec(<2 x i32> %a) {
-; CHECK-LABEL: @ctlz_make_undef_vec(
+define <2 x i32> @ctlz_no_zero_vec(<2 x i32> %a) {
+; CHECK-LABEL: @ctlz_no_zero_vec(
 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[A:%.*]], <i32 8, i32 8>
 ; CHECK-NEXT:    [[CTLZ:%.*]] = tail call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> [[OR]], i1 true)
 ; CHECK-NEXT:    ret <2 x i32> [[CTLZ]]
@@ -321,24 +321,24 @@ define <2 x i32> @ctlz_make_undef_vec(<2 x i32> %a) {
   ret <2 x i32> %ctlz
 }
 
-define i32 @cttz_undef(i32 %Value) nounwind {
-; CHECK-LABEL: @cttz_undef(
-; CHECK-NEXT:    ret i32 undef
+define i32 @cttz_poison(i32 %Value) {
+; CHECK-LABEL: @cttz_poison(
+; CHECK-NEXT:    ret i32 poison
 ;
   %cttz = call i32 @llvm.cttz.i32(i32 0, i1 true)
   ret i32 %cttz
 }
 
-define <2 x i32> @cttz_undef_vec(<2 x i32> %Value) nounwind {
-; CHECK-LABEL: @cttz_undef_vec(
-; CHECK-NEXT:    ret <2 x i32> undef
+define <2 x i32> @cttz_poison_vec(<2 x i32> %Value) {
+; CHECK-LABEL: @cttz_poison_vec(
+; CHECK-NEXT:    ret <2 x i32> poison
 ;
   %cttz = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> zeroinitializer, i1 true)
   ret <2 x i32> %cttz
 }
 
-define i32 @cttz_make_undef(i32 %a) {
-; CHECK-LABEL: @cttz_make_undef(
+define i32 @cttz_no_zero(i32 %a) {
+; CHECK-LABEL: @cttz_no_zero(
 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A:%.*]], 8
 ; CHECK-NEXT:    [[CTTZ:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[OR]], i1 true), !range [[RNG3:![0-9]+]]
 ; CHECK-NEXT:    ret i32 [[CTTZ]]
@@ -348,8 +348,8 @@ define i32 @cttz_make_undef(i32 %a) {
   ret i32 %cttz
 }
 
-define <2 x i32> @cttz_make_undef_vec(<2 x i32> %a) {
-; CHECK-LABEL: @cttz_make_undef_vec(
+define <2 x i32> @cttz_no_zero_vec(<2 x i32> %a) {
+; CHECK-LABEL: @cttz_no_zero_vec(
 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[A:%.*]], <i32 8, i32 8>
 ; CHECK-NEXT:    [[CTTZ:%.*]] = tail call <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[OR]], i1 true)
 ; CHECK-NEXT:    ret <2 x i32> [[CTTZ]]

diff  --git a/llvm/test/Transforms/InstSimplify/ConstProp/bitcount.ll b/llvm/test/Transforms/InstSimplify/ConstProp/bitcount.ll
index f737653a6f3bc..5d020e9677e3b 100644
--- a/llvm/test/Transforms/InstSimplify/ConstProp/bitcount.ll
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/bitcount.ll
@@ -48,9 +48,9 @@ define i32 @cttz_zero_defined() {
   ret i32 %x
 }
 
-define i32 @cttz_zero_undefined() {
-; CHECK-LABEL: @cttz_zero_undefined(
-; CHECK-NEXT:    ret i32 undef
+define i32 @cttz_zero_is_poison() {
+; CHECK-LABEL: @cttz_zero_is_poison(
+; CHECK-NEXT:    ret i32 poison
 ;
   %x = call i32 @llvm.cttz.i32(i32 0, i1 true)
   ret i32 %x
@@ -64,9 +64,9 @@ define i33 @ctlz_zero_defined() {
   ret i33 %x
 }
 
-define i33 @ctlz_zero_undefined() {
-; CHECK-LABEL: @ctlz_zero_undefined(
-; CHECK-NEXT:    ret i33 undef
+define i33 @ctlz_zero_is_poison() {
+; CHECK-LABEL: @ctlz_zero_is_poison(
+; CHECK-NEXT:    ret i33 poison
 ;
   %x = call i33 @llvm.ctlz.i33(i33 0, i1 true)
   ret i33 %x
@@ -88,9 +88,9 @@ define i32 @cttz_undef_defined() {
   ret i32 %x
 }
 
-define i32 @cttz_undef_undefined() {
-; CHECK-LABEL: @cttz_undef_undefined(
-; CHECK-NEXT:    ret i32 undef
+define i32 @cttz_undef_zero_is_poison() {
+; CHECK-LABEL: @cttz_undef_zero_is_poison(
+; CHECK-NEXT:    ret i32 poison
 ;
   %x = call i32 @llvm.cttz.i32(i32 undef, i1 true)
   ret i32 %x
@@ -104,9 +104,9 @@ define i33 @ctlz_undef_defined() {
   ret i33 %x
 }
 
-define i33 @ctlz_undef_undefined() {
-; CHECK-LABEL: @ctlz_undef_undefined(
-; CHECK-NEXT:    ret i33 undef
+define i33 @ctlz_undef_zero_is_poison() {
+; CHECK-LABEL: @ctlz_undef_zero_is_poison(
+; CHECK-NEXT:    ret i33 poison
 ;
   %x = call i33 @llvm.ctlz.i33(i33 undef, i1 true)
   ret i33 %x
@@ -144,9 +144,9 @@ define <2 x i32> @cttz_vector_undef_defined() {
   ret <2 x i32> %x
 }
 
-define <2 x i32> @cttz_vector_undef_undefined() {
-; CHECK-LABEL: @cttz_vector_undef_undefined(
-; CHECK-NEXT:    ret <2 x i32> undef
+define <2 x i32> @cttz_vector_undef_zero_is_poison() {
+; CHECK-LABEL: @cttz_vector_undef_zero_is_poison(
+; CHECK-NEXT:    ret <2 x i32> poison
 ;
   %x = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> <i32 0, i32 undef>, i1 true)
   ret <2 x i32> %x
@@ -168,9 +168,9 @@ define <2 x i33> @ctlz_vector_undef_defined() {
   ret <2 x i33> %x
 }
 
-define <2 x i33> @ctlz_vector_undef_undefined() {
-; CHECK-LABEL: @ctlz_vector_undef_undefined(
-; CHECK-NEXT:    ret <2 x i33> undef
+define <2 x i33> @ctlz_vector_undef_zero_is_poison() {
+; CHECK-LABEL: @ctlz_vector_undef_zero_is_poison(
+; CHECK-NEXT:    ret <2 x i33> poison
 ;
   %x = call <2 x i33> @llvm.ctlz.v2i33(<2 x i33> <i33 0, i33 undef>, i1 true)
   ret <2 x i33> %x


        


More information about the llvm-commits mailing list