[llvm] 1e5f814 - [InstCombine] Fix infinite recursion in ashr/xor vector fold.
David Green via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 4 02:24:32 PDT 2021
Author: David Green
Date: 2021-11-04T09:24:27Z
New Revision: 1e5f814302f8c24bdcc6f79623b86bd32231278f
URL: https://github.com/llvm/llvm-project/commit/1e5f814302f8c24bdcc6f79623b86bd32231278f
DIFF: https://github.com/llvm/llvm-project/commit/1e5f814302f8c24bdcc6f79623b86bd32231278f.diff
LOG: [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
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
llvm/test/Transforms/InstCombine/xor-ashr.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index d3b5cf3fa4b4e..7e40e358b6a22 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -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()));
diff --git a/llvm/test/Transforms/InstCombine/xor-ashr.ll b/llvm/test/Transforms/InstCombine/xor-ashr.ll
index 570a2b33fd59a..7ec863fd119cb 100644
--- a/llvm/test/Transforms/InstCombine/xor-ashr.ll
+++ b/llvm/test/Transforms/InstCombine/xor-ashr.ll
@@ -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) {
More information about the llvm-commits
mailing list