DenseMap<Value *, InsertElementInst *> VectorToInsertElement;
// Maps extract Scalar to the corresponding extractelement instruction in the
// basic block. Only one extractelement per block should be emitted.
- DenseMap<Value *, DenseMap<BasicBlock *, Value *>> ScalarToEEs;
+ DenseMap<Value *, DenseMap<BasicBlock *, Instruction *>> ScalarToEEs;
// Extract all of the elements with the external uses.
for (const auto &ExternalUse : ExternalUses) {
Value *Scalar = ExternalUse.Scalar;
// current block.
auto EEIt = It->second.find(Builder.GetInsertBlock());
if (EEIt != It->second.end()) {
- auto *I = cast<Instruction>(EEIt->second);
+ Instruction *I = EEIt->second;
if (Builder.GetInsertPoint() != Builder.GetInsertBlock()->end() &&
Builder.GetInsertPoint()->comesBefore(I))
I->moveBefore(&*Builder.GetInsertPoint());
} else {
Ex = Builder.CreateExtractElement(Vec, Lane);
}
- ScalarToEEs[Scalar].try_emplace(Builder.GetInsertBlock(), Ex);
+ if (auto *I = dyn_cast<Instruction>(Ex))
+ ScalarToEEs[Scalar].try_emplace(Builder.GetInsertBlock(), I);
}
// The then branch of the previous if may produce constants, since 0
// operand might be a constant.
--- /dev/null
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -passes="slp-vectorizer" -mtriple=aarch64--linux-gnu -S %s | FileCheck %s
+
+define i16 @foo(ptr %p1, ptr %p2) {
+; CHECK-LABEL: @foo(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: store i32 0, ptr [[P1:%.*]], align 1
+; CHECK-NEXT: [[CONST_MAT:%.*]] = or i32 0, 0
+; CHECK-NEXT: store <2 x i32> zeroinitializer, ptr [[P2:%.*]], align 1
+; CHECK-NEXT: ret i16 0
+;
+entry:
+ %const1 = bitcast i32 0 to i32
+ %const = bitcast i32 0 to i32
+ store i32 %const, ptr %p1, align 1
+ %const_mat = or i32 %const, 0
+ %v_332.imagp = getelementptr { i32, i32 }, ptr %p2, i32 0, i32 1
+ store i32 %const, ptr %p2, align 1
+ store i32 %const1, ptr %v_332.imagp, align 1
+ ret i16 0
+}