[llvm] 8d76fbb - [VectorCombine] fix crashing on match of non-canonical fneg
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 17 07:47:57 PDT 2022
Author: Sanjay Patel
Date: 2022-10-17T10:47:48-04:00
New Revision: 8d76fbb5f0659bba47a7f38847550a2bc8bbf0c1
URL: https://github.com/llvm/llvm-project/commit/8d76fbb5f0659bba47a7f38847550a2bc8bbf0c1
DIFF: https://github.com/llvm/llvm-project/commit/8d76fbb5f0659bba47a7f38847550a2bc8bbf0c1.diff
LOG: [VectorCombine] fix crashing on match of non-canonical fneg
We can't assume that operand 0 is the negated operand because
the matcher handles "fsub -0.0, X" (and also +0.0 with FMF).
By capturing the extract within the match, we avoid the bug
and make the transform more robust (can't assume that this
pass will only see canonical IR).
Added:
Modified:
llvm/lib/Transforms/Vectorize/VectorCombine.cpp
llvm/test/Transforms/VectorCombine/X86/extract-fneg-insert.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
index 7046859c26d61..a21add2d47256 100644
--- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
+++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
@@ -550,10 +550,15 @@ bool VectorCombine::foldInsExtFNeg(Instruction &I) {
m_ConstantInt(Index))))
return false;
+ // Note: This handles the canonical fneg instruction and "fsub -0.0, X".
Value *SrcVec;
- if (!match(FNeg, m_FNeg(m_ExtractElt(m_Value(SrcVec), m_SpecificInt(Index)))))
+ Instruction *Extract;
+ if (!match(FNeg, m_FNeg(m_CombineAnd(
+ m_Instruction(Extract),
+ m_ExtractElt(m_Value(SrcVec), m_SpecificInt(Index))))))
return false;
+ // TODO: We could handle this with a length-changing shuffle.
if (SrcVec->getType() != VecTy)
return false;
@@ -577,7 +582,6 @@ bool VectorCombine::foldInsExtFNeg(Instruction &I) {
// If the extract has one use, it will be eliminated, so count it in the
// original cost. If it has more than one use, ignore the cost because it will
// be the same before/after.
- Instruction *Extract = cast<Instruction>(FNeg->getOperand(0));
if (Extract->hasOneUse())
OldCost += TTI.getVectorInstrCost(*Extract, VecTy, Index);
diff --git a/llvm/test/Transforms/VectorCombine/X86/extract-fneg-insert.ll b/llvm/test/Transforms/VectorCombine/X86/extract-fneg-insert.ll
index 0abccb128b734..1e95cbd350610 100644
--- a/llvm/test/Transforms/VectorCombine/X86/extract-fneg-insert.ll
+++ b/llvm/test/Transforms/VectorCombine/X86/extract-fneg-insert.ll
@@ -154,3 +154,31 @@ define <4 x float> @ext12_v4f32(<4 x float> %x, <4 x float> %y) {
%r = insertelement <4 x float> %y, float %n, i32 12
ret <4 x float> %r
}
+
+; This used to crash because we assumed matching a true, unary fneg instruction.
+
+define <2 x float> @ext1_v2f32_fsub(<2 x float> %x) {
+; CHECK-LABEL: @ext1_v2f32_fsub(
+; CHECK-NEXT: [[TMP1:%.*]] = fneg <2 x float> [[X:%.*]]
+; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x float> [[X]], <2 x float> [[TMP1]], <2 x i32> <i32 0, i32 3>
+; CHECK-NEXT: ret <2 x float> [[R]]
+;
+ %e = extractelement <2 x float> %x, i32 1
+ %s = fsub float -0.0, %e
+ %r = insertelement <2 x float> %x, float %s, i32 1
+ ret <2 x float> %r
+}
+
+; This used to crash because we assumed matching a true, unary fneg instruction.
+
+define <2 x float> @ext1_v2f32_fsub_fmf(<2 x float> %x, <2 x float> %y) {
+; CHECK-LABEL: @ext1_v2f32_fsub_fmf(
+; CHECK-NEXT: [[TMP1:%.*]] = fneg nnan nsz <2 x float> [[X:%.*]]
+; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x float> [[Y:%.*]], <2 x float> [[TMP1]], <2 x i32> <i32 0, i32 3>
+; CHECK-NEXT: ret <2 x float> [[R]]
+;
+ %e = extractelement <2 x float> %x, i32 1
+ %s = fsub nsz nnan float 0.0, %e
+ %r = insertelement <2 x float> %y, float %s, i32 1
+ ret <2 x float> %r
+}
More information about the llvm-commits
mailing list