R600/SI: Use S_ADD_U32 and S_SUB_U32 for low half of 64-bit operations
[oota-llvm.git] / test / CodeGen / R600 / add_i64.ll
1 ; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs< %s | FileCheck -check-prefix=SI %s
2
3
4 declare i32 @llvm.r600.read.tidig.x() readnone
5
6 ; SI-LABEL: @test_i64_vreg:
7 ; SI: V_ADD_I32
8 ; SI: V_ADDC_U32
9 define void @test_i64_vreg(i64 addrspace(1)* noalias %out, i64 addrspace(1)* noalias %inA, i64 addrspace(1)* noalias %inB) {
10   %tid = call i32 @llvm.r600.read.tidig.x() readnone
11   %a_ptr = getelementptr i64 addrspace(1)* %inA, i32 %tid
12   %b_ptr = getelementptr i64 addrspace(1)* %inB, i32 %tid
13   %a = load i64 addrspace(1)* %a_ptr
14   %b = load i64 addrspace(1)* %b_ptr
15   %result = add i64 %a, %b
16   store i64 %result, i64 addrspace(1)* %out
17   ret void
18 }
19
20 ; Check that the SGPR add operand is correctly moved to a VGPR.
21 ; SI-LABEL: @sgpr_operand:
22 ; SI: V_ADD_I32
23 ; SI: V_ADDC_U32
24 define void @sgpr_operand(i64 addrspace(1)* noalias %out, i64 addrspace(1)* noalias %in, i64 addrspace(1)* noalias %in_bar, i64 %a) {
25   %foo = load i64 addrspace(1)* %in, align 8
26   %result = add i64 %foo, %a
27   store i64 %result, i64 addrspace(1)* %out
28   ret void
29 }
30
31 ; Swap the arguments. Check that the SGPR -> VGPR copy works with the
32 ; SGPR as other operand.
33 ;
34 ; SI-LABEL: @sgpr_operand_reversed:
35 ; SI: V_ADD_I32
36 ; SI: V_ADDC_U32
37 define void @sgpr_operand_reversed(i64 addrspace(1)* noalias %out, i64 addrspace(1)* noalias %in, i64 %a) {
38   %foo = load i64 addrspace(1)* %in, align 8
39   %result = add i64 %a, %foo
40   store i64 %result, i64 addrspace(1)* %out
41   ret void
42 }
43
44
45 ; SI-LABEL: @test_v2i64_sreg:
46 ; SI: S_ADD_U32
47 ; SI: S_ADDC_U32
48 ; SI: S_ADD_U32
49 ; SI: S_ADDC_U32
50 define void @test_v2i64_sreg(<2 x i64> addrspace(1)* noalias %out, <2 x i64> %a, <2 x i64> %b) {
51   %result = add <2 x i64> %a, %b
52   store <2 x i64> %result, <2 x i64> addrspace(1)* %out
53   ret void
54 }
55
56 ; SI-LABEL: @test_v2i64_vreg:
57 ; SI: V_ADD_I32
58 ; SI: V_ADDC_U32
59 ; SI: V_ADD_I32
60 ; SI: V_ADDC_U32
61 define void @test_v2i64_vreg(<2 x i64> addrspace(1)* noalias %out, <2 x i64> addrspace(1)* noalias %inA, <2 x i64> addrspace(1)* noalias %inB) {
62   %tid = call i32 @llvm.r600.read.tidig.x() readnone
63   %a_ptr = getelementptr <2 x i64> addrspace(1)* %inA, i32 %tid
64   %b_ptr = getelementptr <2 x i64> addrspace(1)* %inB, i32 %tid
65   %a = load <2 x i64> addrspace(1)* %a_ptr
66   %b = load <2 x i64> addrspace(1)* %b_ptr
67   %result = add <2 x i64> %a, %b
68   store <2 x i64> %result, <2 x i64> addrspace(1)* %out
69   ret void
70 }
71
72 ; SI-LABEL: @trunc_i64_add_to_i32
73 ; SI: S_LOAD_DWORD s[[SREG0:[0-9]+]]
74 ; SI: S_LOAD_DWORD s[[SREG1:[0-9]+]]
75 ; SI: S_ADD_I32 [[SRESULT:s[0-9]+]], s[[SREG1]], s[[SREG0]]
76 ; SI-NOT: ADDC
77 ; SI: V_MOV_B32_e32 [[VRESULT:v[0-9]+]], [[SRESULT]]
78 ; SI: BUFFER_STORE_DWORD [[VRESULT]],
79 define void @trunc_i64_add_to_i32(i32 addrspace(1)* %out, i64 %a, i64 %b) {
80   %add = add i64 %b, %a
81   %trunc = trunc i64 %add to i32
82   store i32 %trunc, i32 addrspace(1)* %out, align 8
83   ret void
84 }