@@ -4070,18 +4070,27 @@ class AggLoadStoreRewriter : public InstVisitor<AggLoadStoreRewriter, bool> {
40704070 // => select cond, gep(ptr1, idx), gep(ptr2, idx)
40714071 // and gep ptr, (select cond, idx1, idx2)
40724072 // => select cond, gep(ptr, idx1), gep(ptr, idx2)
4073+ // We also allow for i1 zext indices, which are equivalent to selects.
40734074 bool unfoldGEPSelect (GetElementPtrInst &GEPI) {
40744075 // Check whether the GEP has exactly one select operand and all indices
40754076 // will become constant after the transform.
4076- SelectInst *Sel = dyn_cast<SelectInst>(GEPI.getPointerOperand ());
4077+ Instruction *Sel = dyn_cast<SelectInst>(GEPI.getPointerOperand ());
40774078 for (Value *Op : GEPI.indices ()) {
40784079 if (auto *SI = dyn_cast<SelectInst>(Op)) {
40794080 if (Sel)
40804081 return false ;
40814082
40824083 Sel = SI;
4083- if (!isa<ConstantInt>(Sel->getTrueValue ()) ||
4084- !isa<ConstantInt>(Sel->getFalseValue ()))
4084+ if (!isa<ConstantInt>(SI->getTrueValue ()) ||
4085+ !isa<ConstantInt>(SI->getFalseValue ()))
4086+ return false ;
4087+ continue ;
4088+ }
4089+ if (auto *ZI = dyn_cast<ZExtInst>(Op)) {
4090+ if (Sel)
4091+ return false ;
4092+ Sel = ZI;
4093+ if (!ZI->getSrcTy ()->isIntegerTy (1 ))
40854094 return false ;
40864095 continue ;
40874096 }
@@ -4107,8 +4116,16 @@ class AggLoadStoreRewriter : public InstVisitor<AggLoadStoreRewriter, bool> {
41074116 return NewOps;
41084117 };
41094118
4110- Value *True = Sel->getTrueValue ();
4111- Value *False = Sel->getFalseValue ();
4119+ Value *Cond, *True, *False;
4120+ if (auto *SI = dyn_cast<SelectInst>(Sel)) {
4121+ Cond = SI->getCondition ();
4122+ True = SI->getTrueValue ();
4123+ False = SI->getFalseValue ();
4124+ } else {
4125+ Cond = Sel->getOperand (0 );
4126+ True = ConstantInt::get (Sel->getType (), 1 );
4127+ False = ConstantInt::get (Sel->getType (), 0 );
4128+ }
41124129 SmallVector<Value *> TrueOps = GetNewOps (True);
41134130 SmallVector<Value *> FalseOps = GetNewOps (False);
41144131
@@ -4123,8 +4140,8 @@ class AggLoadStoreRewriter : public InstVisitor<AggLoadStoreRewriter, bool> {
41234140 IRB.CreateGEP (Ty, FalseOps[0 ], ArrayRef (FalseOps).drop_front (),
41244141 False->getName () + " .sroa.gep" , NW);
41254142
4126- Value *NSel = IRB. CreateSelect (Sel-> getCondition (), NTrue, NFalse,
4127- Sel->getName () + " .sroa.sel" );
4143+ Value *NSel =
4144+ IRB. CreateSelect (Cond, NTrue, NFalse, Sel->getName () + " .sroa.sel" );
41284145 Visited.erase (&GEPI);
41294146 GEPI.replaceAllUsesWith (NSel);
41304147 GEPI.eraseFromParent ();
0 commit comments