/// elements.
bool containsPoisonElement() const;
+ /// Return true if this is a vector constant that includes any strictly undef
+ /// (not poison) elements.
+ bool containsUndefElement() const;
+
/// Return true if this is a fixed width vector constant that includes
/// any constant expressions.
bool containsConstantExpression() const;
this, [&](const auto *C) { return isa<PoisonValue>(C); });
}
+bool Constant::containsUndefElement() const {
+ return containsUndefinedElement(this, [&](const auto *C) {
+ return isa<UndefValue>(C) && !isa<PoisonValue>(C);
+ });
+}
+
bool Constant::containsConstantExpression() const {
if (auto *VTy = dyn_cast<FixedVectorType>(getType())) {
for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
return BinaryOperator::CreateLShr(
ConstantInt::get(Ty, APInt::getSignMask(BitWidth)), X);
- // The only way to shift out the 1 is with an over-shift, and that would
- // be poison either way.
- if (!I.hasNoUnsignedWrap()) {
+ // The only way to shift out the 1 is with an over-shift, so that would
+ // be poison with or without "nuw". Undef is excluded because (undef << X)
+ // is not undef (it is zero).
+ Constant *ConstantOne = cast<Constant>(Op0);
+ if (!I.hasNoUnsignedWrap() && !ConstantOne->containsUndefElement()) {
I.setHasNoUnsignedWrap();
return &I;
}
define <3 x i1> @p2_vec_undef0(<3 x i8> %val, <3 x i8> %bits) {
; CHECK-LABEL: @p2_vec_undef0(
-; CHECK-NEXT: [[T0:%.*]] = shl nuw <3 x i8> <i8 1, i8 undef, i8 1>, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl <3 x i8> <i8 1, i8 undef, i8 1>, [[BITS:%.*]]
; CHECK-NEXT: call void @use3i8(<3 x i8> [[T0]])
; CHECK-NEXT: [[VAL_HIGHBITS:%.*]] = lshr <3 x i8> [[VAL:%.*]], [[BITS]]
; CHECK-NEXT: [[R:%.*]] = icmp eq <3 x i8> [[VAL_HIGHBITS]], zeroinitializer
define <3 x i1> @p2_vec_undef0(<3 x i8> %val, <3 x i8> %bits) {
; CHECK-LABEL: @p2_vec_undef0(
-; CHECK-NEXT: [[T0:%.*]] = shl nuw <3 x i8> <i8 1, i8 undef, i8 1>, [[BITS:%.*]]
+; CHECK-NEXT: [[T0:%.*]] = shl <3 x i8> <i8 1, i8 undef, i8 1>, [[BITS:%.*]]
; CHECK-NEXT: call void @use3i8(<3 x i8> [[T0]])
; CHECK-NEXT: [[VAL_HIGHBITS:%.*]] = lshr <3 x i8> [[VAL:%.*]], [[BITS]]
; CHECK-NEXT: [[R:%.*]] = icmp ne <3 x i8> [[VAL_HIGHBITS]], zeroinitializer