@@ -82,7 +82,9 @@ IN THE SOFTWARE.
8282#include " common/debug/Dump.hpp"
8383#include " Compiler/IGCPassSupport.h"
8484#include " common/LLVMWarningsPush.hpp"
85+ #include " llvmWrapper/IR/Instructions.h"
8586#include < llvm/IR/InstIterator.h>
87+ #include < llvm/IR/InlineAsm.h>
8688#include " common/LLVMWarningsPop.hpp"
8789#include < algorithm>
8890#include " Probe/Assertion.h"
@@ -1017,6 +1019,37 @@ DeSSA::getInsEltRoot(Value* Val) const
10171019 return RI->second ;
10181020}
10191021
1022+ // / <summary>
1023+ // / Identify if an instruction has partial write semantics
1024+ // / </summary>
1025+ // / <param name="Inst"></param>
1026+ // / <returns> the index of the source partial-write operand</returns>
1027+ static
1028+ int getPartialWriteSource (Value *Inst)
1029+ {
1030+ if (isa<InsertElementInst>(Inst))
1031+ return 0 ; // source 0 is the original value
1032+ if (auto CI = dyn_cast<CallInst>(Inst)) {
1033+ // only handle inline-asm with simple destination
1034+ if (CI->isInlineAsm () && !CI->getType ()->isStructTy ()) {
1035+ InlineAsm* IA = cast<InlineAsm>(IGCLLVM::getCalledValue (CI));
1036+ StringRef constraintStr (IA->getConstraintString ());
1037+ SmallVector<StringRef, 8 > constraints;
1038+ constraintStr.split (constraints, ' ,' );
1039+ for (int i = 0 ; i < (int )constraints.size (); i++) {
1040+ unsigned destID;
1041+ if (constraints[i].getAsInteger (10 , destID) == 0 ) {
1042+ // constraint-string indicates that source(i-1) and
1043+ // destination should be the same vISA variable
1044+ if (i > 0 && destID == 0 )
1045+ return (i - 1 );
1046+ }
1047+ }
1048+ }
1049+ }
1050+ return -1 ;
1051+ }
1052+
10201053void
10211054DeSSA::CoalesceInsertElementsForBasicBlock (BasicBlock* Blk)
10221055{
@@ -1035,9 +1068,10 @@ DeSSA::CoalesceInsertElementsForBasicBlock(BasicBlock* Blk)
10351068 }
10361069
10371070 // For keeping the existing behavior of InsEltMap unchanged
1038- if (isa<InsertElementInst>(Inst))
1071+ auto PWSrcIdx = getPartialWriteSource (Inst);
1072+ if (PWSrcIdx >= 0 )
10391073 {
1040- Value* origSrcV = Inst->getOperand (0 );
1074+ Value* origSrcV = Inst->getOperand (PWSrcIdx );
10411075 Value* SrcV = getAliasee (origSrcV);
10421076 if (SrcV != Inst && isArgOrNeededInst (origSrcV))
10431077 {
@@ -1076,21 +1110,22 @@ DeSSA::CoalesceInsertElementsForBasicBlock(BasicBlock* Blk)
10761110 // extend the liveness of InsertElement due to union
10771111 for (unsigned i = 0 ; i < Inst->getNumOperands (); ++i) {
10781112 Value* SrcV = Inst->getOperand (i);
1079- if (isa<InsertElementInst> (SrcV)) {
1113+ if (getPartialWriteSource (SrcV) >= 0 ) {
10801114 Value* RootV = getInsEltRoot (SrcV);
10811115 if (RootV != SrcV) {
10821116 LV->HandleVirtRegUse (RootV, Blk, Inst, true );
10831117 }
10841118 }
10851119 }
10861120
1087- if (!isa<InsertElementInst>(Inst)) {
1121+ auto PWSrcIdx = getPartialWriteSource (Inst);
1122+ if (PWSrcIdx < 0 ) {
10881123 continue ;
10891124 }
10901125 // handle InsertElement
10911126 InsEltMapAddValue (Inst);
10921127
1093- Value* SrcV = Inst->getOperand (0 );
1128+ Value* SrcV = Inst->getOperand (PWSrcIdx );
10941129 if (isa<Instruction>(SrcV) || isa<Argument>(SrcV)) {
10951130 if (!LV->isLiveAt (SrcV, Inst)) {
10961131 Instruction* SrcDef = dyn_cast<Instruction>(SrcV);
0 commit comments