Skip to content

Commit 56e4d3d

Browse files
committed
Implement select.ll:test12*
This transforms code like this: %C = or %A, %B %D = select %cond, %C, %A into: %C = select %cond, %B, 0 %D = or %A, %C Since B is often a constant, the select can often be eliminated. In any case, this reduces the usage count of A, allowing subsequent optimizations to happen. This xform applies when the operator is any of: add, sub, mul, or, xor, and, shl, shr llvm-svn: 12800
1 parent be68fd0 commit 56e4d3d

File tree

1 file changed

+108
-0
lines changed

1 file changed

+108
-0
lines changed

llvm/lib/Transforms/Scalar/InstructionCombining.cpp

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
20942142
Instruction *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

Comments
 (0)