summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp8
-rw-r--r--llvm/test/Transforms/InstCombine/insert-extract-shuffle.ll27
2 files changed, 35 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index 6c3aa3ad6c9..732a786ceb7 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -413,6 +413,14 @@ static void replaceExtractElements(InsertElementInst *InsElt,
if (InsertionBlock != InsElt->getParent())
return;
+ // TODO: This restriction matches the check in visitInsertElementInst() and
+ // prevents an infinite loop caused by not turning the extract/insert pair
+ // into a shuffle. We really should not need either check, but we're lacking
+ // folds for shufflevectors because we're afraid to generate shuffle masks
+ // that the backend can't handle.
+ if (InsElt->hasOneUse() && isa<InsertElementInst>(InsElt->user_back()))
+ return;
+
auto *WideVec = new ShuffleVectorInst(ExtVecOp, UndefValue::get(ExtVecType),
ConstantVector::get(ExtendMask));
diff --git a/llvm/test/Transforms/InstCombine/insert-extract-shuffle.ll b/llvm/test/Transforms/InstCombine/insert-extract-shuffle.ll
index 163c3368699..4507deb7f02 100644
--- a/llvm/test/Transforms/InstCombine/insert-extract-shuffle.ll
+++ b/llvm/test/Transforms/InstCombine/insert-extract-shuffle.ll
@@ -237,3 +237,30 @@ end:
ret double %mu
}
+; https://llvm.org/bugs/show_bug.cgi?id=30923
+; Delete the widening shuffle if we're not going to reduce the extract/insert to a shuffle.
+
+define <4 x float> @PR30923(<2 x float> %x) {
+; CHECK-LABEL: @PR30923(
+; CHECK-NEXT: bb1:
+; CHECK-NEXT: [[EXT1:%.*]] = extractelement <2 x float> %x, i32 1
+; CHECK-NEXT: store float [[EXT1]], float* undef, align 4
+; CHECK-NEXT: br label %bb2
+; CHECK: bb2:
+; CHECK-NEXT: [[EXT2:%.*]] = extractelement <2 x float> %x, i32 0
+; CHECK-NEXT: [[INS1:%.*]] = insertelement <4 x float> <float 0.000000e+00, float 0.000000e+00, float undef, float undef>, float [[EXT2]], i32 2
+; CHECK-NEXT: [[INS2:%.*]] = insertelement <4 x float> [[INS1]], float [[EXT1]], i32 3
+; CHECK-NEXT: ret <4 x float> [[INS2]]
+;
+bb1:
+ %ext1 = extractelement <2 x float> %x, i32 1
+ store float %ext1, float* undef, align 4
+ br label %bb2
+
+bb2:
+ %widen = shufflevector <2 x float> %x, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
+ %ext2 = extractelement <4 x float> %widen, i32 0
+ %ins1 = insertelement <4 x float> <float 0.0, float 0.0, float undef, float undef>, float %ext2, i32 2
+ %ins2 = insertelement <4 x float> %ins1, float %ext1, i32 3
+ ret <4 x float> %ins2
+}
OpenPOWER on IntegriCloud