@@ -113,10 +113,16 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
113113 LoadInst *LI, GetElementPtrInst *GEP, GlobalVariable *GV, CmpInst &ICI,
114114 ConstantInt *AndCst) {
115115 if (LI->isVolatile () || LI->getType () != GEP->getResultElementType () ||
116- GV->getValueType () != GEP-> getSourceElementType () || !GV->isConstant () ||
116+ ! GV->getValueType ()-> isArrayTy () || !GV->isConstant () ||
117117 !GV->hasDefinitiveInitializer ())
118118 return nullptr ;
119119
120+ Type *GEPSrcEltTy = GEP->getSourceElementType ();
121+ if (GEPSrcEltTy->isArrayTy ())
122+ GEPSrcEltTy = GEPSrcEltTy->getArrayElementType ();
123+ if (GV->getValueType ()->getArrayElementType () != GEPSrcEltTy)
124+ return nullptr ;
125+
120126 Constant *Init = GV->getInitializer ();
121127 if (!isa<ConstantArray>(Init) && !isa<ConstantDataArray>(Init))
122128 return nullptr ;
@@ -127,12 +133,19 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
127133 return nullptr ;
128134
129135 // 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 .
131137 //
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)))
136149 return nullptr ;
137150
138151 // Check that indices after the variable are constants and in-range for the
@@ -141,7 +154,7 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
141154 SmallVector<unsigned , 4 > LaterIndices;
142155
143156 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) {
145158 ConstantInt *Idx = dyn_cast<ConstantInt>(GEP->getOperand (i));
146159 if (!Idx)
147160 return nullptr ; // Variable index.
@@ -163,7 +176,7 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
163176 LaterIndices.push_back (IdxVal);
164177 }
165178
166- Value *Idx = GEP->getOperand (2 );
179+ Value *Idx = GEP->getOperand (GEPIdxOp );
167180 // If the index type is non-canonical, wait for it to be canonicalized.
168181 if (Idx->getType () != DL.getIndexType (GEP->getType ()))
169182 return nullptr ;
0 commit comments