llvm.org GIT mirror llvm / 9ad2c7e
R600: Move add/sub with overflow out of AMDILISelLowering Add more tests for these. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211517 91177308-0d34-0410-b5e6-96231b3b80d8 Matt Arsenault 5 years ago
7 changed file(s) with 258 addition(s) and 21 deletion(s). Raw diff Collapse all Expand all
305305 setOperationAction(ISD::UMUL_LOHI, VT, Expand);
306306 setOperationAction(ISD::SDIVREM, VT, Custom);
307307 setOperationAction(ISD::UDIVREM, VT, Custom);
308 setOperationAction(ISD::ADDC, VT, Expand);
309 setOperationAction(ISD::SUBC, VT, Expand);
310 setOperationAction(ISD::ADDE, VT, Expand);
311 setOperationAction(ISD::SUBE, VT, Expand);
308312 setOperationAction(ISD::SELECT, VT, Expand);
309313 setOperationAction(ISD::VSELECT, VT, Expand);
310314 setOperationAction(ISD::SELECT_CC, VT, Expand);
2020 // TargetLowering Class Implementation Begins
2121 //===----------------------------------------------------------------------===//
2222 void AMDGPUTargetLowering::InitAMDILLowering() {
23 static const MVT::SimpleValueType types[] = {
24 MVT::i32,
25 MVT::i64,
26 MVT::v2i32,
27 MVT::v4i32
28 };
29
30 for (MVT VT : types) {
31 setOperationAction(ISD::SUBE, VT, Expand);
32 setOperationAction(ISD::SUBC, VT, Expand);
33 setOperationAction(ISD::ADDE, VT, Expand);
34 setOperationAction(ISD::ADDC, VT, Expand);
35 }
36
37 setOperationAction(ISD::SUBC, MVT::Other, Expand);
38 setOperationAction(ISD::ADDE, MVT::Other, Expand);
39 setOperationAction(ISD::ADDC, MVT::Other, Expand);
40
4123 setOperationAction(ISD::BRCOND, MVT::Other, Custom);
42
4324 setSelectIsExpensive(true); // FIXME: This makes no sense at all
4425 }
4526
167167 setOperationAction(ISD::SRA_PARTS, MVT::i32, Custom);
168168
169169 setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
170
171 const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
172 for (MVT VT : ScalarIntVTs) {
173 setOperationAction(ISD::ADDC, VT, Expand);
174 setOperationAction(ISD::SUBC, VT, Expand);
175 setOperationAction(ISD::ADDE, VT, Expand);
176 setOperationAction(ISD::SUBE, VT, Expand);
177 }
170178
171179 setBooleanContents(ZeroOrNegativeOneBooleanContent);
172180 setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
0 ; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs< %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
1 ; RUN: llc -march=r600 -mcpu=cypress -verify-machineinstrs< %s
2
3 declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
4 declare { i64, i1 } @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone
5
6 ; FUNC-LABEL: @saddo_i64_zext
7 define void @saddo_i64_zext(i64 addrspace(1)* %out, i64 %a, i64 %b) nounwind {
8 %sadd = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %a, i64 %b) nounwind
9 %val = extractvalue { i64, i1 } %sadd, 0
10 %carry = extractvalue { i64, i1 } %sadd, 1
11 %ext = zext i1 %carry to i64
12 %add2 = add i64 %val, %ext
13 store i64 %add2, i64 addrspace(1)* %out, align 8
14 ret void
15 }
16
17 ; FUNC-LABEL: @s_saddo_i32
18 define void @s_saddo_i32(i32 addrspace(1)* %out, i1 addrspace(1)* %carryout, i32 %a, i32 %b) nounwind {
19 %sadd = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a, i32 %b) nounwind
20 %val = extractvalue { i32, i1 } %sadd, 0
21 %carry = extractvalue { i32, i1 } %sadd, 1
22 store i32 %val, i32 addrspace(1)* %out, align 4
23 store i1 %carry, i1 addrspace(1)* %carryout
24 ret void
25 }
26
27 ; FUNC-LABEL: @v_saddo_i32
28 define void @v_saddo_i32(i32 addrspace(1)* %out, i1 addrspace(1)* %carryout, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
29 %a = load i32 addrspace(1)* %aptr, align 4
30 %b = load i32 addrspace(1)* %bptr, align 4
31 %sadd = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a, i32 %b) nounwind
32 %val = extractvalue { i32, i1 } %sadd, 0
33 %carry = extractvalue { i32, i1 } %sadd, 1
34 store i32 %val, i32 addrspace(1)* %out, align 4
35 store i1 %carry, i1 addrspace(1)* %carryout
36 ret void
37 }
38
39 ; FUNC-LABEL: @s_saddo_i64
40 define void @s_saddo_i64(i64 addrspace(1)* %out, i1 addrspace(1)* %carryout, i64 %a, i64 %b) nounwind {
41 %sadd = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %a, i64 %b) nounwind
42 %val = extractvalue { i64, i1 } %sadd, 0
43 %carry = extractvalue { i64, i1 } %sadd, 1
44 store i64 %val, i64 addrspace(1)* %out, align 8
45 store i1 %carry, i1 addrspace(1)* %carryout
46 ret void
47 }
48
49 ; FUNC-LABEL: @v_saddo_i64
50 ; SI: V_ADD_I32
51 ; SI: V_ADDC_U32
52 define void @v_saddo_i64(i64 addrspace(1)* %out, i1 addrspace(1)* %carryout, i64 addrspace(1)* %aptr, i64 addrspace(1)* %bptr) nounwind {
53 %a = load i64 addrspace(1)* %aptr, align 4
54 %b = load i64 addrspace(1)* %bptr, align 4
55 %sadd = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %a, i64 %b) nounwind
56 %val = extractvalue { i64, i1 } %sadd, 0
57 %carry = extractvalue { i64, i1 } %sadd, 1
58 store i64 %val, i64 addrspace(1)* %out, align 8
59 store i1 %carry, i1 addrspace(1)* %carryout
60 ret void
61 }
0 ; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs< %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
1 ; RUN: llc -march=r600 -mcpu=cypress -verify-machineinstrs< %s
2
3 declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
4 declare { i64, i1 } @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone
5
6 ; FUNC-LABEL: @ssubo_i64_zext
7 define void @ssubo_i64_zext(i64 addrspace(1)* %out, i64 %a, i64 %b) nounwind {
8 %ssub = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 %a, i64 %b) nounwind
9 %val = extractvalue { i64, i1 } %ssub, 0
10 %carry = extractvalue { i64, i1 } %ssub, 1
11 %ext = zext i1 %carry to i64
12 %add2 = add i64 %val, %ext
13 store i64 %add2, i64 addrspace(1)* %out, align 8
14 ret void
15 }
16
17 ; FUNC-LABEL: @s_ssubo_i32
18 define void @s_ssubo_i32(i32 addrspace(1)* %out, i1 addrspace(1)* %carryout, i32 %a, i32 %b) nounwind {
19 %ssub = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %a, i32 %b) nounwind
20 %val = extractvalue { i32, i1 } %ssub, 0
21 %carry = extractvalue { i32, i1 } %ssub, 1
22 store i32 %val, i32 addrspace(1)* %out, align 4
23 store i1 %carry, i1 addrspace(1)* %carryout
24 ret void
25 }
26
27 ; FUNC-LABEL: @v_ssubo_i32
28 define void @v_ssubo_i32(i32 addrspace(1)* %out, i1 addrspace(1)* %carryout, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
29 %a = load i32 addrspace(1)* %aptr, align 4
30 %b = load i32 addrspace(1)* %bptr, align 4
31 %ssub = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %a, i32 %b) nounwind
32 %val = extractvalue { i32, i1 } %ssub, 0
33 %carry = extractvalue { i32, i1 } %ssub, 1
34 store i32 %val, i32 addrspace(1)* %out, align 4
35 store i1 %carry, i1 addrspace(1)* %carryout
36 ret void
37 }
38
39 ; FUNC-LABEL: @s_ssubo_i64
40 ; SI: S_SUB_I32
41 ; SI: S_SUBB_U32
42 define void @s_ssubo_i64(i64 addrspace(1)* %out, i1 addrspace(1)* %carryout, i64 %a, i64 %b) nounwind {
43 %ssub = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 %a, i64 %b) nounwind
44 %val = extractvalue { i64, i1 } %ssub, 0
45 %carry = extractvalue { i64, i1 } %ssub, 1
46 store i64 %val, i64 addrspace(1)* %out, align 8
47 store i1 %carry, i1 addrspace(1)* %carryout
48 ret void
49 }
50
51 ; FUNC-LABEL: @v_ssubo_i64
52 ; SI: V_SUB_I32_e32
53 ; SI: V_SUBB_U32_e32
54 define void @v_ssubo_i64(i64 addrspace(1)* %out, i1 addrspace(1)* %carryout, i64 addrspace(1)* %aptr, i64 addrspace(1)* %bptr) nounwind {
55 %a = load i64 addrspace(1)* %aptr, align 4
56 %b = load i64 addrspace(1)* %bptr, align 4
57 %ssub = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 %a, i64 %b) nounwind
58 %val = extractvalue { i64, i1 } %ssub, 0
59 %carry = extractvalue { i64, i1 } %ssub, 1
60 store i64 %val, i64 addrspace(1)* %out, align 8
61 store i1 %carry, i1 addrspace(1)* %carryout
62 ret void
63 }
None ; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs< %s | FileCheck -check-prefix=SI %s
0 ; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs< %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
1 ; RUN: llc -march=r600 -mcpu=cypress -verify-machineinstrs< %s
12
3 declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
24 declare { i64, i1 } @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone
35
4 ; SI-LABEL: @uaddo_i64_zext
6 ; FUNC-LABEL: @uaddo_i64_zext
57 ; SI: ADD
68 ; SI: ADDC
79 ; SI: ADDC
1416 store i64 %add2, i64 addrspace(1)* %out, align 8
1517 ret void
1618 }
19
20 ; FUNC-LABEL: @s_uaddo_i32
21 ; SI: S_ADD_I32
22 define void @s_uaddo_i32(i32 addrspace(1)* %out, i1 addrspace(1)* %carryout, i32 %a, i32 %b) nounwind {
23 %uadd = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a, i32 %b) nounwind
24 %val = extractvalue { i32, i1 } %uadd, 0
25 %carry = extractvalue { i32, i1 } %uadd, 1
26 store i32 %val, i32 addrspace(1)* %out, align 4
27 store i1 %carry, i1 addrspace(1)* %carryout
28 ret void
29 }
30
31 ; FUNC-LABEL: @v_uaddo_i32
32 ; SI: V_ADD_I32
33 define void @v_uaddo_i32(i32 addrspace(1)* %out, i1 addrspace(1)* %carryout, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
34 %a = load i32 addrspace(1)* %aptr, align 4
35 %b = load i32 addrspace(1)* %bptr, align 4
36 %uadd = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a, i32 %b) nounwind
37 %val = extractvalue { i32, i1 } %uadd, 0
38 %carry = extractvalue { i32, i1 } %uadd, 1
39 store i32 %val, i32 addrspace(1)* %out, align 4
40 store i1 %carry, i1 addrspace(1)* %carryout
41 ret void
42 }
43
44 ; FUNC-LABEL: @s_uaddo_i64
45 ; SI: S_ADD_I32
46 ; SI: S_ADDC_U32
47 define void @s_uaddo_i64(i64 addrspace(1)* %out, i1 addrspace(1)* %carryout, i64 %a, i64 %b) nounwind {
48 %uadd = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %a, i64 %b) nounwind
49 %val = extractvalue { i64, i1 } %uadd, 0
50 %carry = extractvalue { i64, i1 } %uadd, 1
51 store i64 %val, i64 addrspace(1)* %out, align 8
52 store i1 %carry, i1 addrspace(1)* %carryout
53 ret void
54 }
55
56 ; FUNC-LABEL: @v_uaddo_i64
57 ; SI: V_ADD_I32
58 ; SI: V_ADDC_U32
59 define void @v_uaddo_i64(i64 addrspace(1)* %out, i1 addrspace(1)* %carryout, i64 addrspace(1)* %aptr, i64 addrspace(1)* %bptr) nounwind {
60 %a = load i64 addrspace(1)* %aptr, align 4
61 %b = load i64 addrspace(1)* %bptr, align 4
62 %uadd = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %a, i64 %b) nounwind
63 %val = extractvalue { i64, i1 } %uadd, 0
64 %carry = extractvalue { i64, i1 } %uadd, 1
65 store i64 %val, i64 addrspace(1)* %out, align 8
66 store i1 %carry, i1 addrspace(1)* %carryout
67 ret void
68 }
0 ; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs< %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
1 ; RUN: llc -march=r600 -mcpu=cypress -verify-machineinstrs< %s
2
3 declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
4 declare { i64, i1 } @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone
5
6 ; FUNC-LABEL: @usubo_i64_zext
7 define void @usubo_i64_zext(i64 addrspace(1)* %out, i64 %a, i64 %b) nounwind {
8 %usub = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %a, i64 %b) nounwind
9 %val = extractvalue { i64, i1 } %usub, 0
10 %carry = extractvalue { i64, i1 } %usub, 1
11 %ext = zext i1 %carry to i64
12 %add2 = add i64 %val, %ext
13 store i64 %add2, i64 addrspace(1)* %out, align 8
14 ret void
15 }
16
17 ; FUNC-LABEL: @s_usubo_i32
18 ; SI: S_SUB_I32
19 define void @s_usubo_i32(i32 addrspace(1)* %out, i1 addrspace(1)* %carryout, i32 %a, i32 %b) nounwind {
20 %usub = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b) nounwind
21 %val = extractvalue { i32, i1 } %usub, 0
22 %carry = extractvalue { i32, i1 } %usub, 1
23 store i32 %val, i32 addrspace(1)* %out, align 4
24 store i1 %carry, i1 addrspace(1)* %carryout
25 ret void
26 }
27
28 ; FUNC-LABEL: @v_usubo_i32
29 ; SI: V_SUBREV_I32_e32
30 define void @v_usubo_i32(i32 addrspace(1)* %out, i1 addrspace(1)* %carryout, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
31 %a = load i32 addrspace(1)* %aptr, align 4
32 %b = load i32 addrspace(1)* %bptr, align 4
33 %usub = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b) nounwind
34 %val = extractvalue { i32, i1 } %usub, 0
35 %carry = extractvalue { i32, i1 } %usub, 1
36 store i32 %val, i32 addrspace(1)* %out, align 4
37 store i1 %carry, i1 addrspace(1)* %carryout
38 ret void
39 }
40
41 ; FUNC-LABEL: @s_usubo_i64
42 ; SI: S_SUB_I32
43 ; SI: S_SUBB_U32
44 define void @s_usubo_i64(i64 addrspace(1)* %out, i1 addrspace(1)* %carryout, i64 %a, i64 %b) nounwind {
45 %usub = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %a, i64 %b) nounwind
46 %val = extractvalue { i64, i1 } %usub, 0
47 %carry = extractvalue { i64, i1 } %usub, 1
48 store i64 %val, i64 addrspace(1)* %out, align 8
49 store i1 %carry, i1 addrspace(1)* %carryout
50 ret void
51 }
52
53 ; FUNC-LABEL: @v_usubo_i64
54 ; SI: V_SUB_I32
55 ; SI: V_SUBB_U32
56 define void @v_usubo_i64(i64 addrspace(1)* %out, i1 addrspace(1)* %carryout, i64 addrspace(1)* %aptr, i64 addrspace(1)* %bptr) nounwind {
57 %a = load i64 addrspace(1)* %aptr, align 4
58 %b = load i64 addrspace(1)* %bptr, align 4
59 %usub = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %a, i64 %b) nounwind
60 %val = extractvalue { i64, i1 } %usub, 0
61 %carry = extractvalue { i64, i1 } %usub, 1
62 store i64 %val, i64 addrspace(1)* %out, align 8
63 store i1 %carry, i1 addrspace(1)* %carryout
64 ret void
65 }