@@ -2091,6 +2091,54 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) {
20912091 return 0 ;
20922092}
20932093
2094+ // / GetSelectFoldableOperands - We want to turn code that looks like this:
2095+ // / %C = or %A, %B
2096+ // / %D = select %cond, %C, %A
2097+ // / into:
2098+ // / %C = select %cond, %B, 0
2099+ // / %D = or %A, %C
2100+ // /
2101+ // / Assuming that the specified instruction is an operand to the select, return
2102+ // / a bitmask indicating which operands of this instruction are foldable if they
2103+ // / equal the other incoming value of the select.
2104+ // /
2105+ static unsigned GetSelectFoldableOperands (Instruction *I) {
2106+ switch (I->getOpcode ()) {
2107+ case Instruction::Add:
2108+ case Instruction::Mul:
2109+ case Instruction::And:
2110+ case Instruction::Or:
2111+ case Instruction::Xor:
2112+ return 3 ; // Can fold through either operand.
2113+ case Instruction::Sub: // Can only fold on the amount subtracted.
2114+ case Instruction::Shl: // Can only fold on the shift amount.
2115+ case Instruction::Shr:
2116+ return 1 ;
2117+ default :
2118+ return 0 ; // Cannot fold
2119+ }
2120+ }
2121+
2122+ // / GetSelectFoldableConstant - For the same transformation as the previous
2123+ // / function, return the identity constant that goes into the select.
2124+ static Constant *GetSelectFoldableConstant (Instruction *I) {
2125+ switch (I->getOpcode ()) {
2126+ default : assert (0 && " This cannot happen!" ); abort ();
2127+ case Instruction::Add:
2128+ case Instruction::Sub:
2129+ case Instruction::Or:
2130+ case Instruction::Xor:
2131+ return Constant::getNullValue (I->getType ());
2132+ case Instruction::Shl:
2133+ case Instruction::Shr:
2134+ return Constant::getNullValue (Type::UByteTy);
2135+ case Instruction::And:
2136+ return ConstantInt::getAllOnesValue (I->getType ());
2137+ case Instruction::Mul:
2138+ return ConstantInt::get (I->getType (), 1 );
2139+ }
2140+ }
2141+
20942142Instruction *InstCombiner::visitSelectInst (SelectInst &SI) {
20952143 Value *CondVal = SI.getCondition ();
20962144 Value *TrueVal = SI.getTrueValue ();
@@ -2150,6 +2198,66 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
21502198 }
21512199 }
21522200
2201+ // See if we can fold the select into one of our operands.
2202+ if (SI.getType ()->isInteger ()) {
2203+ // See the comment above GetSelectFoldableOperands for a description of the
2204+ // transformation we are doing here.
2205+ if (Instruction *TVI = dyn_cast<Instruction>(TrueVal))
2206+ if (TVI->hasOneUse () && TVI->getNumOperands () == 2 &&
2207+ !isa<Constant>(FalseVal))
2208+ if (unsigned SFO = GetSelectFoldableOperands (TVI)) {
2209+ unsigned OpToFold = 0 ;
2210+ if ((SFO & 1 ) && FalseVal == TVI->getOperand (0 )) {
2211+ OpToFold = 1 ;
2212+ } else if ((SFO & 2 ) && FalseVal == TVI->getOperand (1 )) {
2213+ OpToFold = 2 ;
2214+ }
2215+
2216+ if (OpToFold) {
2217+ Constant *C = GetSelectFoldableConstant (TVI);
2218+ std::string Name = TVI->getName (); TVI->setName (" " );
2219+ Instruction *NewSel =
2220+ new SelectInst (SI.getCondition (), TVI->getOperand (2 -OpToFold), C,
2221+ Name);
2222+ InsertNewInstBefore (NewSel, SI);
2223+ if (BinaryOperator *BO = dyn_cast<BinaryOperator>(TVI))
2224+ return BinaryOperator::create (BO->getOpcode (), FalseVal, NewSel);
2225+ else if (ShiftInst *SI = dyn_cast<ShiftInst>(TVI))
2226+ return new ShiftInst (SI->getOpcode (), FalseVal, NewSel);
2227+ else {
2228+ assert (0 && " Unknown instruction!!" );
2229+ }
2230+ }
2231+ }
2232+
2233+ if (Instruction *FVI = dyn_cast<Instruction>(FalseVal))
2234+ if (FVI->hasOneUse () && FVI->getNumOperands () == 2 &&
2235+ !isa<Constant>(TrueVal))
2236+ if (unsigned SFO = GetSelectFoldableOperands (FVI)) {
2237+ unsigned OpToFold = 0 ;
2238+ if ((SFO & 1 ) && TrueVal == FVI->getOperand (0 )) {
2239+ OpToFold = 1 ;
2240+ } else if ((SFO & 2 ) && TrueVal == FVI->getOperand (1 )) {
2241+ OpToFold = 2 ;
2242+ }
2243+
2244+ if (OpToFold) {
2245+ Constant *C = GetSelectFoldableConstant (FVI);
2246+ std::string Name = FVI->getName (); FVI->setName (" " );
2247+ Instruction *NewSel =
2248+ new SelectInst (SI.getCondition (), C, FVI->getOperand (2 -OpToFold),
2249+ Name);
2250+ InsertNewInstBefore (NewSel, SI);
2251+ if (BinaryOperator *BO = dyn_cast<BinaryOperator>(FVI))
2252+ return BinaryOperator::create (BO->getOpcode (), TrueVal, NewSel);
2253+ else if (ShiftInst *SI = dyn_cast<ShiftInst>(FVI))
2254+ return new ShiftInst (SI->getOpcode (), TrueVal, NewSel);
2255+ else {
2256+ assert (0 && " Unknown instruction!!" );
2257+ }
2258+ }
2259+ }
2260+ }
21532261 return 0 ;
21542262}
21552263
0 commit comments