@@ -568,23 +568,47 @@ class OpLowerer {
568
568
return make_error<StringError>(
569
569
" typedBufferStore data must be a vector of 4 elements" ,
570
570
inconvertibleErrorCode ());
571
- Value *Data0 =
572
- IRB.CreateExtractElement (Data, ConstantInt::get (Int32Ty, 0 ));
573
- Value *Data1 =
574
- IRB.CreateExtractElement (Data, ConstantInt::get (Int32Ty, 1 ));
575
- Value *Data2 =
576
- IRB.CreateExtractElement (Data, ConstantInt::get (Int32Ty, 2 ));
577
- Value *Data3 =
578
- IRB.CreateExtractElement (Data, ConstantInt::get (Int32Ty, 3 ));
579
-
580
- std::array<Value *, 8 > Args{Handle, Index0, Index1, Data0,
581
- Data1, Data2, Data3, Mask};
571
+
572
+ // Since we're post-scalarizer, we likely have a vector that's constructed
573
+ // solely for the argument of the store. If so, just use the scalar values
574
+ // from before they're inserted into the temporary.
575
+ std::array<Value *, 4 > DataElements{nullptr , nullptr , nullptr , nullptr };
576
+ auto *IEI = dyn_cast<InsertElementInst>(Data);
577
+ while (IEI) {
578
+ auto *IndexOp = dyn_cast<ConstantInt>(IEI->getOperand (2 ));
579
+ if (!IndexOp)
580
+ break ;
581
+ size_t IndexVal = IndexOp->getZExtValue ();
582
+ assert (IndexVal < 4 && " Too many elements for buffer store" );
583
+ DataElements[IndexVal] = IEI->getOperand (1 );
584
+ IEI = dyn_cast<InsertElementInst>(IEI->getOperand (0 ));
585
+ }
586
+
587
+ // If for some reason we weren't able to forward the arguments from the
588
+ // scalarizer artifact, then we need to actually extract elements from the
589
+ // vector.
590
+ for (int I = 0 , E = 4 ; I != E; ++I)
591
+ if (DataElements[I] == nullptr )
592
+ DataElements[I] =
593
+ IRB.CreateExtractElement (Data, ConstantInt::get (Int32Ty, I));
594
+
595
+ std::array<Value *, 8 > Args{
596
+ Handle, Index0, Index1, DataElements[0 ],
597
+ DataElements[1 ], DataElements[2 ], DataElements[3 ], Mask};
582
598
Expected<CallInst *> OpCall =
583
599
OpBuilder.tryCreateOp (OpCode::BufferStore, Args, CI->getName ());
584
600
if (Error E = OpCall.takeError ())
585
601
return E;
586
602
587
603
CI->eraseFromParent ();
604
+ // Clean up any leftover `insertelement`s
605
+ IEI = dyn_cast<InsertElementInst>(Data);
606
+ while (IEI && IEI->use_empty ()) {
607
+ InsertElementInst *Tmp = IEI;
608
+ IEI = dyn_cast<InsertElementInst>(IEI->getOperand (0 ));
609
+ Tmp->eraseFromParent ();
610
+ }
611
+
588
612
return Error::success ();
589
613
});
590
614
}
0 commit comments