[InstCombine] Fix infinite recursion in ashr/xor vector fold.
The added test has poison lanes due to the vector shuffle. This can cause an infinite loop of combines in instcombine where it folds xor(ashr, -1) -> select (icmp slt 0), -1, 0 -> sext (icmp slt 0) -> xor(ashr, -1). We usually prevent this by checking that the xor constant is not -1, but with vectors some of the lanes may be -1, some may be poison. So this changes the way we detect that from "!C1->isAllOnesValue()" to "!match(C1, m_AllOnes())", which is more able to detect that some of the lanes are poison. Fixes PR52397
This commit is contained in:
parent
341cc1b411
commit
1e5f814302
|
@ -3601,7 +3601,7 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
|
|||
if (match(Op0, m_OneUse(m_TruncOrSelf(
|
||||
m_AShr(m_Value(X), m_APIntAllowUndef(CA))))) &&
|
||||
*CA == X->getType()->getScalarSizeInBits() - 1 &&
|
||||
!C1->isAllOnesValue()) {
|
||||
!match(C1, m_AllOnes())) {
|
||||
assert(!C1->isZeroValue() && "Unexpected xor with 0");
|
||||
Value *ICmp =
|
||||
Builder.CreateICmpSGT(X, Constant::getAllOnesValue(X->getType()));
|
||||
|
|
|
@ -90,6 +90,23 @@ define i8 @wrongimm(i16 %add) {
|
|||
ret i8 %x
|
||||
}
|
||||
|
||||
; Some of the lanes of the xor/ashr are unused, becoming poison.
|
||||
define <4 x i32> @vectorpoison(<6 x i32> %0) {
|
||||
; CHECK-LABEL: @vectorpoison(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[NEG:%.*]] = ashr <6 x i32> [[TMP0:%.*]], <i32 31, i32 31, i32 31, i32 31, i32 31, i32 31>
|
||||
; CHECK-NEXT: [[SHR:%.*]] = xor <6 x i32> [[NEG]], <i32 -1, i32 -1, i32 -1, i32 poison, i32 poison, i32 poison>
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <6 x i32> [[SHR]], <6 x i32> poison, <4 x i32> <i32 0, i32 1, i32 0, i32 2>
|
||||
; CHECK-NEXT: ret <4 x i32> [[TMP1]]
|
||||
;
|
||||
entry:
|
||||
%neg = xor <6 x i32> %0, <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>
|
||||
%shr = ashr <6 x i32> %neg, <i32 31, i32 31, i32 31, i32 31, i32 31, i32 31>
|
||||
%1 = shufflevector <6 x i32> %shr, <6 x i32> poison, <4 x i32> <i32 0, i32 1, i32 0, i32 2>
|
||||
ret <4 x i32> %1
|
||||
}
|
||||
|
||||
|
||||
; One use
|
||||
|
||||
define i16 @extrause(i16 %add) {
|
||||
|
|
Loading…
Reference in New Issue