llvm.org GIT mirror llvm / 726ebd6
PerformSubCombine to work on integers larger than i128. Fixes a crasher. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138354 91177308-0d34-0410-b5e6-96231b3b80d8 Nick Lewycky 8 years ago
2 changed file(s) with 20 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
1329213292 // X86 can't encode an immediate LHS of a sub. See if we can push the
1329313293 // negation into a preceding instruction.
1329413294 if (ConstantSDNode *C = dyn_cast(Op0)) {
13295 uint64_t Op0C = C->getSExtValue();
13296
1329713295 // If the RHS of the sub is a XOR with one use and a constant, invert the
1329813296 // immediate. Then add one to the LHS of the sub so we can turn
1329913297 // X-Y -> X+~Y+1, saving one register.
1330013298 if (Op1->hasOneUse() && Op1.getOpcode() == ISD::XOR &&
1330113299 isa(Op1.getOperand(1))) {
13302 uint64_t XorC = cast(Op1.getOperand(1))->getSExtValue();
13300 APInt XorC = cast(Op1.getOperand(1))->getAPIntValue();
1330313301 EVT VT = Op0.getValueType();
1330413302 SDValue NewXor = DAG.getNode(ISD::XOR, Op1.getDebugLoc(), VT,
1330513303 Op1.getOperand(0),
1330613304 DAG.getConstant(~XorC, VT));
1330713305 return DAG.getNode(ISD::ADD, N->getDebugLoc(), VT, NewXor,
13308 DAG.getConstant(Op0C+1, VT));
13306 DAG.getConstant(C->getAPIntValue()+1, VT));
1330913307 }
1331013308 }
1331113309
0 ; RUN: llc -march=x86-64 -O2 < %s
1
2 define void @test(i64 %add127.tr.i2686) {
3 entry:
4 %conv143.i2687 = and i64 %add127.tr.i2686, 72057594037927935
5 %conv76.i2623 = zext i64 %conv143.i2687 to i128
6 %mul148.i2338 = mul i128 0, %conv76.i2623
7 %add149.i2339 = add i128 %mul148.i2338, 0
8 %add.i2303 = add i128 0, 170141183460469229370468033484042534912
9 %add6.i2270 = add i128 %add.i2303, 0
10 %sub58.i2271 = sub i128 %add6.i2270, %add149.i2339
11 %add71.i2272 = add i128 %sub58.i2271, 0
12 %add105.i2273 = add i128 %add71.i2272, 0
13 %add116.i2274 = add i128 %add105.i2273, 0
14 %shr124.i2277 = lshr i128 %add116.i2274, 56
15 %add116.tr.i2280 = trunc i128 %add116.i2274 to i64
16 ret void
17 }