@@ -113,10 +113,16 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
113
113
LoadInst *LI, GetElementPtrInst *GEP, GlobalVariable *GV, CmpInst &ICI,
114
114
ConstantInt *AndCst) {
115
115
if (LI->isVolatile () || LI->getType () != GEP->getResultElementType () ||
116
- GV->getValueType () != GEP-> getSourceElementType () || !GV->isConstant () ||
116
+ ! GV->getValueType ()-> isArrayTy () || !GV->isConstant () ||
117
117
!GV->hasDefinitiveInitializer ())
118
118
return nullptr ;
119
119
120
+ Type *GEPSrcEltTy = GEP->getSourceElementType ();
121
+ if (GEPSrcEltTy->isArrayTy ())
122
+ GEPSrcEltTy = GEPSrcEltTy->getArrayElementType ();
123
+ if (GV->getValueType ()->getArrayElementType () != GEPSrcEltTy)
124
+ return nullptr ;
125
+
120
126
Constant *Init = GV->getInitializer ();
121
127
if (!isa<ConstantArray>(Init) && !isa<ConstantDataArray>(Init))
122
128
return nullptr ;
@@ -127,12 +133,19 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
127
133
return nullptr ;
128
134
129
135
// There are many forms of this optimization we can handle, for now, just do
130
- // the simple index into a single-dimensional array.
136
+ // the simple index into a single-dimensional array or elements of equal size .
131
137
//
132
- // Require: GEP GV, 0, i {{, constant indices}}
133
- if (GEP->getNumOperands () < 3 || !isa<ConstantInt>(GEP->getOperand (1 )) ||
134
- !cast<ConstantInt>(GEP->getOperand (1 ))->isZero () ||
135
- isa<Constant>(GEP->getOperand (2 )))
138
+ // Require: GEP [n x i8] GV, 0, Idx {{, constant indices}}
139
+ // Or: GEP i8 GV, Idx
140
+
141
+ unsigned GEPIdxOp = 1 ;
142
+ if (GEP->getSourceElementType ()->isArrayTy ()) {
143
+ GEPIdxOp = 2 ;
144
+ if (!match (GEP->getOperand (1 ), m_ZeroInt ()))
145
+ return nullptr ;
146
+ }
147
+ if (GEP->getNumOperands () < GEPIdxOp + 1 ||
148
+ isa<Constant>(GEP->getOperand (GEPIdxOp)))
136
149
return nullptr ;
137
150
138
151
// Check that indices after the variable are constants and in-range for the
@@ -141,7 +154,7 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
141
154
SmallVector<unsigned , 4 > LaterIndices;
142
155
143
156
Type *EltTy = Init->getType ()->getArrayElementType ();
144
- for (unsigned i = 3 , e = GEP->getNumOperands (); i != e; ++i) {
157
+ for (unsigned i = GEPIdxOp + 1 , e = GEP->getNumOperands (); i != e; ++i) {
145
158
ConstantInt *Idx = dyn_cast<ConstantInt>(GEP->getOperand (i));
146
159
if (!Idx)
147
160
return nullptr ; // Variable index.
@@ -163,7 +176,7 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
163
176
LaterIndices.push_back (IdxVal);
164
177
}
165
178
166
- Value *Idx = GEP->getOperand (2 );
179
+ Value *Idx = GEP->getOperand (GEPIdxOp );
167
180
// If the index type is non-canonical, wait for it to be canonicalized.
168
181
if (Idx->getType () != DL.getIndexType (GEP->getType ()))
169
182
return nullptr ;
0 commit comments