ExtendMask.push_back(UndefValue::get(IntType));
Value *ExtVecOp = ExtElt->getVectorOperand();
+ auto *ExtVecOpInst = dyn_cast<Instruction>(ExtVecOp);
+ BasicBlock *InsertionBlock = (ExtVecOpInst && !isa<PHINode>(ExtVecOpInst))
+ ? ExtVecOpInst->getParent()
+ : ExtElt->getParent();
+
+ // TODO: This restriction matches the basic block check below when creating
+ // new extractelement instructions. If that limitation is removed, this one
+ // could also be removed. But for now, we just bail out to ensure that we
+ // will replace the extractelement instruction that is feeding our
+ // insertelement instruction. This allows the insertelement to then be
+ // replaced by a shufflevector. If the insertelement is not replaced, we can
+ // induce infinite looping because there's an optimization for extractelement
+ // that will delete our widening shuffle. This would trigger another attempt
+ // here to create that shuffle, and we spin forever.
+ if (InsertionBlock != InsElt->getParent())
+ return;
+
auto *WideVec = new ShuffleVectorInst(ExtVecOp, UndefValue::get(ExtVecType),
ConstantVector::get(ExtendMask));
// (as long as it's not a PHI) or at the start of the basic block of the
// extract, so any subsequent extracts in the same basic block can use it.
// TODO: Insert before the earliest ExtractElementInst that is replaced.
- auto *ExtVecOpInst = dyn_cast<Instruction>(ExtVecOp);
if (ExtVecOpInst && !isa<PHINode>(ExtVecOpInst))
WideVec->insertAfter(ExtVecOpInst);
else
ret <4 x double> %tmp4
}
+; PR26354: https://llvm.org/bugs/show_bug.cgi?id=26354
+; Don't create a shufflevector if we know that we're not going to replace the insertelement.
+
+define double @pr26354(<2 x double>* %tmp, i1 %B) {
+; CHECK-LABEL: @pr26354(
+; CHECK: %ld = load <2 x double>, <2 x double>* %tmp
+; CHECK-NEXT: %e1 = extractelement <2 x double> %ld, i32 0
+; CHECK-NEXT: br i1 %B, label %if, label %end
+; CHECK: if:
+; CHECK-NEXT: %e2 = extractelement <2 x double> %ld, i32 1
+; CHECK-NEXT: %i1 = insertelement <4 x double>
+; CHECK-NEXT: br label %end
+
+entry:
+ %ld = load <2 x double>, <2 x double>* %tmp
+ %e1 = extractelement <2 x double> %ld, i32 0
+ %e2 = extractelement <2 x double> %ld, i32 1
+ br i1 %B, label %if, label %end
+
+if:
+ %i1 = insertelement <4 x double> zeroinitializer, double %e2, i32 3
+ br label %end
+
+end:
+ %ph = phi <4 x double> [ undef, %entry ], [ %i1, %if ]
+ %e3 = extractelement <4 x double> %ph, i32 1
+ %mu = fmul double %e1, %e3
+ ret double %mu
+}
+