llvm.org GIT mirror llvm / 502e0aa
Improve 64-subtraction of immediates when parts of the immediate can fit in the literal field of an instruction. E.g., long long foo(long long a) { return a - 734439407618LL; } rdar://7038284 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@108339 91177308-0d34-0410-b5e6-96231b3b80d8 Jim Grosbach 10 years ago
5 changed file(s) with 172 addition(s) and 13 deletion(s). Raw diff Collapse all Expand all
16931693 }
16941694
16951695 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1696 // The assume-no-carry-in form uses the negation of the input since add/sub
1697 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
1698 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
1699 // details.
16961700 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
16971701 (SUBri GPR:$src, so_imm_neg:$imm)>;
1698
1699 //def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
1700 // (SUBSri GPR:$src, so_imm_neg:$imm)>;
1701 //def : ARMPat<(adde GPR:$src, so_imm_neg:$imm),
1702 // (SBCri GPR:$src, so_imm_neg:$imm)>;
1702 def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
1703 (SUBSri GPR:$src, so_imm_neg:$imm)>;
1704 // The with-carry-in form matches bitwise not instead of the negation.
1705 // Effectively, the inverse interpretation of the carry flag already accounts
1706 // for part of the negation.
1707 def : ARMPat<(adde GPR:$src, so_imm_not:$imm),
1708 (SBCri GPR:$src, so_imm_not:$imm)>;
17031709
17041710 // Note: These are implemented in C++ code, because they have to generate
17051711 // ADD/SUBrs instructions, which use a complex pattern that a xform function
120120 def imm0_255_neg : PatLeaf<(i32 imm), [{
121121 return (uint32_t)(-N->getZExtValue()) < 255;
122122 }], imm_neg_XFORM>;
123
124 def imm0_255_not : PatLeaf<(i32 imm), [{
125 return (uint32_t)(~N->getZExtValue()) < 255;
126 }], imm_comp_XFORM>;
123127
124128 // Define Thumb2 specific addressing modes.
125129
13901394 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
13911395
13921396 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1397 // The assume-no-carry-in form uses the negation of the input since add/sub
1398 // assume opposite meanings of the carry flag (i.e., carry == !borrow).
1399 // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory
1400 // details.
1401 // The AddedComplexity preferences the first variant over the others since
1402 // it can be shrunk to a 16-bit wide encoding, while the others cannot.
13931403 let AddedComplexity = 1 in
1394 def : T2Pat<(add GPR:$src, imm0_255_neg:$imm),
1395 (t2SUBri GPR:$src, imm0_255_neg:$imm)>;
1396 def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
1397 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
1398 def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
1399 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
1404 def : T2Pat<(add GPR:$src, imm0_255_neg:$imm),
1405 (t2SUBri GPR:$src, imm0_255_neg:$imm)>;
1406 def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
1407 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
1408 def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
1409 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
1410 let AddedComplexity = 1 in
1411 def : T2Pat<(addc GPR:$src, imm0_255_neg:$imm),
1412 (t2SUBSri GPR:$src, imm0_255_neg:$imm)>;
1413 def : T2Pat<(addc GPR:$src, t2_so_imm_neg:$imm),
1414 (t2SUBSri GPR:$src, t2_so_imm_neg:$imm)>;
1415 // The with-carry-in form matches bitwise not instead of the negation.
1416 // Effectively, the inverse interpretation of the carry flag already accounts
1417 // for part of the negation.
1418 let AddedComplexity = 1 in
1419 def : T2Pat<(adde GPR:$src, imm0_255_not:$imm),
1420 (t2SBCSri GPR:$src, imm0_255_not:$imm)>;
1421 def : T2Pat<(adde GPR:$src, t2_so_imm_not:$imm),
1422 (t2SBCSri GPR:$src, t2_so_imm_not:$imm)>;
14001423
14011424 // Select Bytes -- for disassembly only
14021425
0 ; RUN: llc -march=arm < %s | FileCheck %s
1
2 ; 171 = 0x000000ab
3 define i64 @f1(i64 %a) {
4 ; CHECK: f1
5 ; CHECK: subs r0, r0, #171
6 ; CHECK: sbc r1, r1, #0
7 %tmp = sub i64 %a, 171
8 ret i64 %tmp
9 }
10
11 ; 66846720 = 0x03fc0000
12 define i64 @f2(i64 %a) {
13 ; CHECK: f2
14 ; CHECK: subs r0, r0, #255, 14
15 ; CHECK: sbc r1, r1, #0
16 %tmp = sub i64 %a, 66846720
17 ret i64 %tmp
18 }
19
20 ; 734439407618 = 0x000000ab00000002
21 define i64 @f3(i64 %a) {
22 ; CHECK: f3
23 ; CHECK: subs r0, r0, #2
24 ; CHECK: sbc r1, r1, #171
25 %tmp = sub i64 %a, 734439407618
26 ret i64 %tmp
27 }
28
None ; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s
0 ; RUN: llc -march=thumb -mattr=+thumb2 < %s | FileCheck %s
11
22 define i64 @f1(i64 %a, i64 %b) {
3 ; CHECK: f1:
3 ; CHECK: f1
44 ; CHECK: subs r0, r0, r2
55 %tmp = sub i64 %a, %b
66 ret i64 %tmp
77 }
8
9 ; 734439407618 = 0x000000ab00000002
10 define i64 @f2(i64 %a) {
11 ; CHECK: f2
12 ; CHECK: subs r0, #2
13 ; CHECK: sbc r1, r1, #171
14 %tmp = sub i64 %a, 734439407618
15 ret i64 %tmp
16 }
17
18 ; 5066626890203138 = 0x0012001200000002
19 define i64 @f3(i64 %a) {
20 ; CHECK: f3
21 ; CHECK: subs r0, #2
22 ; CHECK: sbc r1, r1, #1179666
23 %tmp = sub i64 %a, 5066626890203138
24 ret i64 %tmp
25 }
26
27 ; 3747052064576897026 = 0x3400340000000002
28 define i64 @f4(i64 %a) {
29 ; CHECK: f4
30 ; CHECK: subs r0, #2
31 ; CHECK: sbc r1, r1, #872428544
32 %tmp = sub i64 %a, 3747052064576897026
33 ret i64 %tmp
34 }
35
36 ; 6221254862626095106 = 0x5656565600000002
37 define i64 @f5(i64 %a) {
38 ; CHECK: f5
39 ; CHECK: subs r0, #2
40 ; CHECK: adc r1, r1, #-1448498775
41 %tmp = sub i64 %a, 6221254862626095106
42 ret i64 %tmp
43 }
44
45 ; 287104476244869122 = 0x03fc000000000002
46 define i64 @f6(i64 %a) {
47 ; CHECK: f6
48 ; CHECK: subs r0, #2
49 ; CHECK: sbc r1, r1, #66846720
50 %tmp = sub i64 %a, 287104476244869122
51 ret i64 %tmp
52 }
53
0 ; RUN: llc -march=thumb -mattr=+thumb2 < %s | FileCheck %s
1
2 ; 171 = 0x000000ab
3 define i64 @f1(i64 %a) {
4 ; CHECK: f1
5 ; CHECK: subs r0, #171
6 ; CHECK: adc r1, r1, #-1
7 %tmp = sub i64 %a, 171
8 ret i64 %tmp
9 }
10
11 ; 1179666 = 0x00120012
12 define i64 @f2(i64 %a) {
13 ; CHECK: f2
14 ; CHECK: subs.w r0, r0, #1179666
15 ; CHECK: adc r1, r1, #-1
16 %tmp = sub i64 %a, 1179666
17 ret i64 %tmp
18 }
19
20 ; 872428544 = 0x34003400
21 define i64 @f3(i64 %a) {
22 ; CHECK: f3
23 ; CHECK: subs.w r0, r0, #872428544
24 ; CHECK: adc r1, r1, #-1
25 %tmp = sub i64 %a, 872428544
26 ret i64 %tmp
27 }
28
29 ; 1448498774 = 0x56565656
30 define i64 @f4(i64 %a) {
31 ; CHECK: f4
32 ; CHECK: subs.w r0, r0, #1448498774
33 ; CHECK: adc r1, r1, #-1
34 %tmp = sub i64 %a, 1448498774
35 ret i64 %tmp
36 }
37
38 ; 66846720 = 0x03fc0000
39 define i64 @f5(i64 %a) {
40 ; CHECK: f5
41 ; CHECK: subs.w r0, r0, #66846720
42 ; CHECK: adc r1, r1, #-1
43 %tmp = sub i64 %a, 66846720
44 ret i64 %tmp
45 }
46
47 ; 734439407618 = 0x000000ab00000002
48 define i64 @f6(i64 %a) {
49 ; CHECK: f6
50 ; CHECK: subs r0, #2
51 ; CHECK: sbc r1, r1, #171
52 %tmp = sub i64 %a, 734439407618
53 ret i64 %tmp
54 }