blob: d4e2dc81405085c22e7c869c147a0d1a07882abd [file] [log] [blame]
Matt Arsenaultf1aebbf2015-11-02 23:30:48 +00001; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
Matt Arsenaultd1649db2014-09-02 19:12:31 +00002
Matt Arsenault9c47dd52016-02-11 06:02:01 +00003declare i32 @llvm.amdgcn.workitem.id.x() readnone
Matt Arsenaultd1649db2014-09-02 19:12:31 +00004
5; This is broken because the low half of the 64-bit add remains on the
6; SALU, but the upper half does not. The addc expects the carry bit
7; set in vcc, which is undefined since the low scalar half add sets
8; scc instead.
9
Tom Stellard79243d92014-10-01 17:15:17 +000010; FUNC-LABEL: {{^}}imp_def_vcc_split_i64_add_0:
Matt Arsenaultf1aebbf2015-11-02 23:30:48 +000011; SI: v_add_i32_e32 v{{[0-9]+}}, vcc, 0x18f, v{{[0-9]+}}
12; SI: v_addc_u32_e32 v{{[0-9]+}}, vcc, 0, v{{[0-9]+}}, vcc
13define void @imp_def_vcc_split_i64_add_0(i64 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %s.val) {
14 %v.val = load volatile i32, i32 addrspace(1)* %in
15 %vec.0 = insertelement <2 x i32> undef, i32 %s.val, i32 0
16 %vec.1 = insertelement <2 x i32> %vec.0, i32 %v.val, i32 1
17 %bc = bitcast <2 x i32> %vec.1 to i64
18 %add = add i64 %bc, 399
19 store i64 %add, i64 addrspace(1)* %out, align 8
20 ret void
21}
22
23; FUNC-LABEL: {{^}}s_imp_def_vcc_split_i64_add_0:
24; SI: s_add_u32 {{s[0-9]+}}, {{s[0-9]+}}, 0x18f
25; SI: s_addc_u32 {{s[0-9]+}}, 0xf423f, 0
26define void @s_imp_def_vcc_split_i64_add_0(i64 addrspace(1)* %out, i32 %val) {
Matt Arsenaultd1649db2014-09-02 19:12:31 +000027 %vec.0 = insertelement <2 x i32> undef, i32 %val, i32 0
28 %vec.1 = insertelement <2 x i32> %vec.0, i32 999999, i32 1
29 %bc = bitcast <2 x i32> %vec.1 to i64
30 %add = add i64 %bc, 399
31 store i64 %add, i64 addrspace(1)* %out, align 8
32 ret void
33}
34
Tom Stellard79243d92014-10-01 17:15:17 +000035; FUNC-LABEL: {{^}}imp_def_vcc_split_i64_add_1:
Matt Arsenault162c1012014-11-18 21:06:58 +000036; SI: v_add_i32
37; SI: v_addc_u32
Matt Arsenaultf1aebbf2015-11-02 23:30:48 +000038define void @imp_def_vcc_split_i64_add_1(i64 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %val0, i64 %val1) {
39 %v.val = load volatile i32, i32 addrspace(1)* %in
40 %vec.0 = insertelement <2 x i32> undef, i32 %val0, i32 0
41 %vec.1 = insertelement <2 x i32> %vec.0, i32 %v.val, i32 1
42 %bc = bitcast <2 x i32> %vec.1 to i64
43 %add = add i64 %bc, %val1
44 store i64 %add, i64 addrspace(1)* %out, align 8
45 ret void
46}
47
48; FUNC-LABEL: {{^}}s_imp_def_vcc_split_i64_add_1:
49; SI: s_add_u32 {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
50; SI: s_addc_u32 {{s[0-9]+}}, 0x1869f, {{s[0-9]+}}
51define void @s_imp_def_vcc_split_i64_add_1(i64 addrspace(1)* %out, i32 %val0, i64 %val1) {
Matt Arsenaultd1649db2014-09-02 19:12:31 +000052 %vec.0 = insertelement <2 x i32> undef, i32 %val0, i32 0
53 %vec.1 = insertelement <2 x i32> %vec.0, i32 99999, i32 1
54 %bc = bitcast <2 x i32> %vec.1 to i64
55 %add = add i64 %bc, %val1
56 store i64 %add, i64 addrspace(1)* %out, align 8
57 ret void
58}
59
60; Doesn't use constants
Matt Arsenaultf1aebbf2015-11-02 23:30:48 +000061; FUNC-LABEL: {{^}}imp_def_vcc_split_i64_add_2:
62; SI: v_add_i32_e32 {{v[0-9]+}}, vcc, {{s[0-9]+}}, {{v[0-9]+}}
63; SI: v_addc_u32_e32 {{v[0-9]+}}, vcc, {{v[0-9]+}}, {{v[0-9]+}}, vcc
Matt Arsenaultd1649db2014-09-02 19:12:31 +000064define void @imp_def_vcc_split_i64_add_2(i64 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %val0, i64 %val1) {
Matt Arsenault9c47dd52016-02-11 06:02:01 +000065 %tid = call i32 @llvm.amdgcn.workitem.id.x() readnone
David Blaikie79e6c742015-02-27 19:29:02 +000066 %gep = getelementptr i32, i32 addrspace(1)* %in, i32 %tid
David Blaikiea79ac142015-02-27 21:17:42 +000067 %load = load i32, i32 addrspace(1)* %gep
Matt Arsenaultd1649db2014-09-02 19:12:31 +000068 %vec.0 = insertelement <2 x i32> undef, i32 %val0, i32 0
69 %vec.1 = insertelement <2 x i32> %vec.0, i32 %load, i32 1
70 %bc = bitcast <2 x i32> %vec.1 to i64
71 %add = add i64 %bc, %val1
72 store i64 %add, i64 addrspace(1)* %out, align 8
73 ret void
74}