@@ -87,20 +87,63 @@ static void fixI8UseChain(Instruction &I,
87
87
return ;
88
88
}
89
89
90
- if (auto *Load = dyn_cast<LoadInst>(&I)) {
91
- if (!I.getType ()->isIntegerTy (8 ))
92
- return ;
90
+ if (auto *Load = dyn_cast<LoadInst>(&I);
91
+ Load && I.getType ()->isIntegerTy (8 )) {
93
92
SmallVector<Value *> NewOperands;
94
93
ProcessOperands (NewOperands);
95
94
Type *ElementType = NewOperands[0 ]->getType ();
96
95
if (auto *AI = dyn_cast<AllocaInst>(NewOperands[0 ]))
97
96
ElementType = AI->getAllocatedType ();
97
+ if (auto *GEP = dyn_cast<GetElementPtrInst>(NewOperands[0 ])) {
98
+ ElementType = GEP->getSourceElementType ();
99
+ if (ElementType->isArrayTy ())
100
+ ElementType = ElementType->getArrayElementType ();
101
+ }
98
102
LoadInst *NewLoad = Builder.CreateLoad (ElementType, NewOperands[0 ]);
99
103
ReplacedValues[Load] = NewLoad;
100
104
ToRemove.push_back (Load);
101
105
return ;
102
106
}
103
107
108
+ if (auto *Load = dyn_cast<LoadInst>(&I);
109
+ Load && isa<ConstantExpr>(Load->getPointerOperand ())) {
110
+ auto *CE = dyn_cast<ConstantExpr>(Load->getPointerOperand ());
111
+ if (!(CE->getOpcode () == Instruction::GetElementPtr))
112
+ return ;
113
+ auto *GEP = dyn_cast<GEPOperator>(CE);
114
+ if (!GEP->getSourceElementType ()->isIntegerTy (8 ))
115
+ return ;
116
+
117
+ Type *ElementType = Load->getType ();
118
+ ConstantInt *Offset = dyn_cast<ConstantInt>(GEP->getOperand (1 ));
119
+ uint32_t ByteOffset = Offset->getZExtValue ();
120
+ uint32_t ElemSize = Load->getDataLayout ().getTypeAllocSize (ElementType);
121
+ uint32_t Index = ByteOffset / ElemSize;
122
+
123
+ Value *PtrOperand = GEP->getPointerOperand ();
124
+ Type *GEPType = GEP->getPointerOperandType ();
125
+
126
+ if (auto *GV = dyn_cast<GlobalVariable>(PtrOperand))
127
+ GEPType = GV->getValueType ();
128
+ if (auto *AI = dyn_cast<AllocaInst>(PtrOperand))
129
+ GEPType = AI->getAllocatedType ();
130
+
131
+ if (auto *ArrTy = dyn_cast<ArrayType>(GEPType))
132
+ GEPType = ArrTy;
133
+ else
134
+ GEPType = ArrayType::get (ElementType, 1 ); // its a scalar
135
+
136
+ Value *NewGEP = Builder.CreateGEP (
137
+ GEPType, PtrOperand, {Builder.getInt32 (0 ), Builder.getInt32 (Index)},
138
+ GEP->getName (), GEP->getNoWrapFlags ());
139
+
140
+ LoadInst *NewLoad = Builder.CreateLoad (ElementType, NewGEP);
141
+ ReplacedValues[Load] = NewLoad;
142
+ Load->replaceAllUsesWith (NewLoad);
143
+ ToRemove.push_back (Load);
144
+ return ;
145
+ }
146
+
104
147
if (auto *BO = dyn_cast<BinaryOperator>(&I)) {
105
148
if (!I.getType ()->isIntegerTy (8 ))
106
149
return ;
@@ -155,6 +198,7 @@ static void fixI8UseChain(Instruction &I,
155
198
Cast->replaceAllUsesWith (Replacement);
156
199
return ;
157
200
}
201
+
158
202
Value *AdjustedCast = nullptr ;
159
203
if (Cast->getOpcode () == Instruction::ZExt)
160
204
AdjustedCast = Builder.CreateZExtOrTrunc (Replacement, Cast->getType ());
@@ -164,6 +208,45 @@ static void fixI8UseChain(Instruction &I,
164
208
if (AdjustedCast)
165
209
Cast->replaceAllUsesWith (AdjustedCast);
166
210
}
211
+ if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {
212
+ if (!GEP->getType ()->isPointerTy () ||
213
+ !GEP->getSourceElementType ()->isIntegerTy (8 ))
214
+ return ;
215
+
216
+ Value *BasePtr = GEP->getPointerOperand ();
217
+ if (ReplacedValues.count (BasePtr))
218
+ BasePtr = ReplacedValues[BasePtr];
219
+
220
+ Type *ElementType = BasePtr->getType ();
221
+
222
+ if (auto *AI = dyn_cast<AllocaInst>(BasePtr))
223
+ ElementType = AI->getAllocatedType ();
224
+ if (auto *GV = dyn_cast<GlobalVariable>(BasePtr))
225
+ ElementType = GV->getValueType ();
226
+
227
+ Type *GEPType = ElementType;
228
+ if (auto *ArrTy = dyn_cast<ArrayType>(ElementType))
229
+ ElementType = ArrTy->getArrayElementType ();
230
+ else
231
+ GEPType = ArrayType::get (ElementType, 1 ); // its a scalar
232
+
233
+ ConstantInt *Offset = dyn_cast<ConstantInt>(GEP->getOperand (1 ));
234
+ // Note: i8 to i32 offset conversion without emitting IR requires constant
235
+ // ints. Since offset conversion is common, we can safely assume Offset is
236
+ // always a ConstantInt, so no need to have a conditional bail out on
237
+ // nullptr, instead assert this is the case.
238
+ assert (Offset && " Offset is expected to be a ConstantInt" );
239
+ uint32_t ByteOffset = Offset->getZExtValue ();
240
+ uint32_t ElemSize = GEP->getDataLayout ().getTypeAllocSize (ElementType);
241
+ assert (ElemSize > 0 && " ElementSize must be set" );
242
+ uint32_t Index = ByteOffset / ElemSize;
243
+ Value *NewGEP = Builder.CreateGEP (
244
+ GEPType, BasePtr, {Builder.getInt32 (0 ), Builder.getInt32 (Index)},
245
+ GEP->getName (), GEP->getNoWrapFlags ());
246
+ ReplacedValues[GEP] = NewGEP;
247
+ GEP->replaceAllUsesWith (NewGEP);
248
+ ToRemove.push_back (GEP);
249
+ }
167
250
}
168
251
169
252
static void upcastI8AllocasAndUses (Instruction &I,
@@ -175,15 +258,12 @@ static void upcastI8AllocasAndUses(Instruction &I,
175
258
176
259
Type *SmallestType = nullptr ;
177
260
178
- for (User *U : AI->users ()) {
179
- auto *Load = dyn_cast<LoadInst>(U);
180
- if (!Load)
181
- continue ;
261
+ auto ProcessLoad = [&](LoadInst *Load) {
182
262
for (User *LU : Load->users ()) {
183
263
Type *Ty = nullptr ;
184
- if (auto *Cast = dyn_cast<CastInst>(LU))
264
+ if (CastInst *Cast = dyn_cast<CastInst>(LU))
185
265
Ty = Cast->getType ();
186
- if (CallInst *CI = dyn_cast<CallInst>(LU)) {
266
+ else if (CallInst *CI = dyn_cast<CallInst>(LU)) {
187
267
if (CI->getIntrinsicID () == Intrinsic::memset)
188
268
Ty = Type::getInt32Ty (CI->getContext ());
189
269
}
@@ -195,6 +275,17 @@ static void upcastI8AllocasAndUses(Instruction &I,
195
275
Ty->getPrimitiveSizeInBits () < SmallestType->getPrimitiveSizeInBits ())
196
276
SmallestType = Ty;
197
277
}
278
+ };
279
+
280
+ for (User *U : AI->users ()) {
281
+ if (auto *Load = dyn_cast<LoadInst>(U))
282
+ ProcessLoad (Load);
283
+ else if (auto *GEP = dyn_cast<GetElementPtrInst>(U)) {
284
+ for (User *GU : GEP->users ()) {
285
+ if (auto *Load = dyn_cast<LoadInst>(GU))
286
+ ProcessLoad (Load);
287
+ }
288
+ }
198
289
}
199
290
200
291
if (!SmallestType)
0 commit comments