diff options
author | Chris Lattner <sabre@nondot.org> | 2011-04-17 01:16:47 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2011-04-17 01:16:47 +0000 |
commit | fba7ca63cc934e52e6bf5d682755c2e99614c8da (patch) | |
tree | 999fbb5fb2668df6d030763f4caec6b82352aa4e /llvm/lib/CodeGen | |
parent | bc204c8043167f52f6b7f7498f33fe2efc0c1854 (diff) | |
download | bcm5719-llvm-fba7ca63cc934e52e6bf5d682755c2e99614c8da.tar.gz bcm5719-llvm-fba7ca63cc934e52e6bf5d682755c2e99614c8da.zip |
fix rdar://9289583 - fast isel should handle non-canonical commutative binops
allowing us to fold the immediate into the 'and' in this case:
int test1(int i) {
return 8&i;
}
llvm-svn: 129653
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index aab23ea1c77..df75c4a88f7 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -122,10 +122,9 @@ unsigned FastISel::getRegForValue(const Value *V) { // only locally. This is because Instructions already have the SSA // def-dominates-use requirement enforced. DenseMap<const Value *, unsigned>::iterator I = FuncInfo.ValueMap.find(V); - if (I != FuncInfo.ValueMap.end()) { - unsigned Reg = I->second; - return Reg; - } + if (I != FuncInfo.ValueMap.end()) + return I->second; + unsigned Reg = LocalValueMap[V]; if (Reg != 0) return Reg; @@ -331,6 +330,26 @@ bool FastISel::SelectBinaryOp(const User *I, unsigned ISDOpcode) { return false; } + // Check if the first operand is a constant, and handle it as "ri". At -O0, + // we don't have anything that canonicalizes operand order. + if (ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(0))) + if (isa<Instruction>(I) && cast<Instruction>(I)->isCommutative()) { + unsigned Op1 = getRegForValue(I->getOperand(1)); + if (Op1 == 0) return false; + + bool Op1IsKill = hasTrivialKill(I->getOperand(1)); + + unsigned ResultReg = FastEmit_ri(VT.getSimpleVT(), VT.getSimpleVT(), + ISDOpcode, Op1, Op1IsKill, + CI->getZExtValue()); + if (ResultReg != 0) { + // We successfully emitted code for the given LLVM Instruction. + UpdateValueMap(I, ResultReg); + return true; + } + } + + unsigned Op0 = getRegForValue(I->getOperand(0)); if (Op0 == 0) // Unhandled operand. Halt "fast" selection and bail. |