@@ -1989,19 +1989,20 @@ bool isSPIRVBuiltinVariable(GlobalVariable *GV,
1989
1989
// / are accumulated in the AccumulatedOffset parameter, which will eventually be
1990
1990
// / used to figure out which index of a variable is being used.
1991
1991
static void replaceUsesOfBuiltinVar (Value *V, const APInt &AccumulatedOffset,
1992
- Function *ReplacementFunc) {
1992
+ Function *ReplacementFunc,
1993
+ GlobalVariable *GV) {
1993
1994
const DataLayout &DL = ReplacementFunc->getParent ()->getDataLayout ();
1994
1995
SmallVector<Instruction *, 4 > InstsToRemove;
1995
1996
for (User *U : V->users ()) {
1996
1997
if (auto *Cast = dyn_cast<CastInst>(U)) {
1997
- replaceUsesOfBuiltinVar (Cast, AccumulatedOffset, ReplacementFunc);
1998
+ replaceUsesOfBuiltinVar (Cast, AccumulatedOffset, ReplacementFunc, GV );
1998
1999
InstsToRemove.push_back (Cast);
1999
2000
} else if (auto *GEP = dyn_cast<GetElementPtrInst>(U)) {
2000
2001
APInt NewOffset = AccumulatedOffset.sextOrTrunc (
2001
2002
DL.getIndexSizeInBits (GEP->getPointerAddressSpace ()));
2002
2003
if (!GEP->accumulateConstantOffset (DL, NewOffset))
2003
2004
llvm_unreachable (" Illegal GEP of a SPIR-V builtin variable" );
2004
- replaceUsesOfBuiltinVar (GEP, NewOffset, ReplacementFunc);
2005
+ replaceUsesOfBuiltinVar (GEP, NewOffset, ReplacementFunc, GV );
2005
2006
InstsToRemove.push_back (GEP);
2006
2007
} else if (auto *Load = dyn_cast<LoadInst>(U)) {
2007
2008
// Figure out which index the accumulated offset corresponds to. If we
@@ -2024,7 +2025,12 @@ static void replaceUsesOfBuiltinVar(Value *V, const APInt &AccumulatedOffset,
2024
2025
} else {
2025
2026
// The function has an index parameter.
2026
2027
if (auto *VecTy = dyn_cast<FixedVectorType>(Load->getType ())) {
2027
- if (!Index.isZero ())
2028
+ // Reconstruct the original global variable vector because
2029
+ // the load type may not match.
2030
+ // global <3 x i64>, load <6 x i32>
2031
+ VecTy = cast<FixedVectorType>(GV->getValueType ());
2032
+ if (!Index.isZero () || DL.getTypeSizeInBits (VecTy) !=
2033
+ DL.getTypeSizeInBits (Load->getType ()))
2028
2034
llvm_unreachable (" Illegal use of a SPIR-V builtin variable" );
2029
2035
Replacement = UndefValue::get (VecTy);
2030
2036
for (unsigned I = 0 ; I < VecTy->getNumElements (); I++) {
@@ -2034,6 +2040,19 @@ static void replaceUsesOfBuiltinVar(Value *V, const APInt &AccumulatedOffset,
2034
2040
Builder.CreateCall (ReplacementFunc, {Builder.getInt32 (I)})),
2035
2041
Builder.getInt32 (I));
2036
2042
}
2043
+ // Insert a bitcast from the reconstructed vector to the load vector
2044
+ // type in case they are different.
2045
+ // Input:
2046
+ // %1 = load <6 x i32>, ptr addrspace(1) %0, align 32
2047
+ // %2 = extractelement <6 x i32> %1, i32 0
2048
+ // %3 = add i32 5, %2
2049
+ // Modified:
2050
+ // < reconstruct global vector elements 0 and 1 >
2051
+ // %2 = insertelement <3 x i64> %0, i64 %1, i32 2
2052
+ // %3 = bitcast <3 x i64> %2 to <6 x i32>
2053
+ // %4 = extractelement <6 x i32> %3, i32 0
2054
+ // %5 = add i32 5, %4
2055
+ Replacement = Builder.CreateBitCast (Replacement, Load->getType ());
2037
2056
} else if (Load->getType () == ScalarTy) {
2038
2057
Replacement = setAttrByCalledFunc (Builder.CreateCall (
2039
2058
ReplacementFunc, {Builder.getInt32 (Index.getZExtValue ())}));
@@ -2087,7 +2106,7 @@ bool lowerBuiltinVariableToCall(GlobalVariable *GV,
2087
2106
Func->setDoesNotAccessMemory ();
2088
2107
}
2089
2108
2090
- replaceUsesOfBuiltinVar (GV, APInt (64 , 0 ), Func);
2109
+ replaceUsesOfBuiltinVar (GV, APInt (64 , 0 ), Func, GV );
2091
2110
return true ;
2092
2111
}
2093
2112
0 commit comments