1; RUN: llc -mtriple=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck -check-prefixes=GCN,GFX8 %s 2; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -verify-machineinstrs < %s | FileCheck -check-prefixes=GCN,GFX9 %s 3 4; GCN-LABEL: reassoc_i32: 5; GCN: s_add_i32 [[ADD1:s[0-9]+]], s{{[0-9]+}}, s{{[0-9]+}} 6; GFX8: v_add_u32_e32 v{{[0-9]+}}, vcc, [[ADD1]], v{{[0-9]+}} 7; GFX9: v_add_u32_e32 v{{[0-9]+}}, [[ADD1]], v{{[0-9]+}} 8define amdgpu_kernel void @reassoc_i32(i32 addrspace(1)* %arg, i32 %x, i32 %y) { 9bb: 10 %tid = tail call i32 @llvm.amdgcn.workitem.id.x() 11 %add1 = add i32 %x, %tid 12 %add2 = add i32 %add1, %y 13 store i32 %add2, i32 addrspace(1)* %arg, align 4 14 ret void 15} 16 17; GCN-LABEL: reassoc_i32_swap_arg_order: 18; GCN: s_add_i32 [[ADD1:s[0-9]+]], s{{[0-9]+}}, s{{[0-9]+}} 19; GFX8: v_add_u32_e32 v{{[0-9]+}}, vcc, [[ADD1]], v{{[0-9]+}} 20; GFX9: v_add_u32_e32 v{{[0-9]+}}, [[ADD1]], v{{[0-9]+}} 21define amdgpu_kernel void @reassoc_i32_swap_arg_order(i32 addrspace(1)* %arg, i32 %x, i32 %y) { 22bb: 23 %tid = tail call i32 @llvm.amdgcn.workitem.id.x() 24 %add1 = add i32 %tid, %x 25 %add2 = add i32 %y, %add1 26 store i32 %add2, i32 addrspace(1)* %arg, align 4 27 ret void 28} 29 30; GCN-LABEL: reassoc_i64: 31; GCN: s_add_u32 [[ADD1L:s[0-9]+]], s{{[0-9]+}}, s{{[0-9]+}} 32; GCN: s_addc_u32 [[ADD1H:s[0-9]+]], s{{[0-9]+}}, s{{[0-9]+}} 33; GFX8-DAG: v_add_u32_e32 v{{[0-9]+}}, vcc, [[ADD1L]], v{{[0-9]+}} 34; GFX9-DAG: v_add_co_u32_e32 v{{[0-9]+}}, vcc, [[ADD1L]], v{{[0-9]+}} 35; GCN-DAG: v_mov_b32_e32 [[VADD1H:v[0-9]+]], [[ADD1H]] 36; GFX8: v_addc_u32_e32 v{{[0-9]+}}, vcc, 0, [[VADD1H]], vcc 37; GFX9: v_addc_co_u32_e32 v{{[0-9]+}}, vcc, 0, [[VADD1H]], vcc 38define amdgpu_kernel void @reassoc_i64(i64 addrspace(1)* %arg, i64 %x, i64 %y) { 39bb: 40 %tid32 = tail call i32 @llvm.amdgcn.workitem.id.x() 41 %tid = zext i32 %tid32 to i64 42 %add1 = add i64 %x, %tid 43 %add2 = add i64 %add1, %y 44 store i64 %add2, i64 addrspace(1)* %arg, align 8 45 ret void 46} 47 48; GCN-LABEL: reassoc_v2i32: 49; GCN: s_add_i32 [[ADD1:s[0-9]+]], s{{[0-9]+}}, s{{[0-9]+}} 50; GCN-DAG: s_add_i32 [[ADD2:s[0-9]+]], s{{[0-9]+}}, s{{[0-9]+}} 51; GFX8-DAG: v_add_u32_e32 v{{[0-9]+}}, vcc, [[ADD1]], v{{[0-9]+}} 52; GFX8: v_add_u32_e32 v{{[0-9]+}}, vcc, [[ADD2]], v{{[0-9]+}} 53; GFX9-DAG: v_add_u32_e32 v{{[0-9]+}}, [[ADD1]], v{{[0-9]+}} 54; GFX9: v_add_u32_e32 v{{[0-9]+}}, [[ADD2]], v{{[0-9]+}} 55define amdgpu_kernel void @reassoc_v2i32(<2 x i32> addrspace(1)* %arg, <2 x i32> %x, <2 x i32> %y) { 56bb: 57 %t1 = tail call i32 @llvm.amdgcn.workitem.id.x() 58 %t2 = tail call i32 @llvm.amdgcn.workitem.id.y() 59 %v1 = insertelement <2 x i32> undef, i32 %t1, i32 0 60 %v2 = insertelement <2 x i32> %v1, i32 %t2, i32 1 61 %add1 = add <2 x i32> %x, %v2 62 %add2 = add <2 x i32> %add1, %y 63 store <2 x i32> %add2, <2 x i32> addrspace(1)* %arg, align 4 64 ret void 65} 66 67; GCN-LABEL: reassoc_i32_nuw: 68; GCN: s_add_i32 [[ADD1:s[0-9]+]], s{{[0-9]+}}, s{{[0-9]+}} 69; GFX8: v_add_u32_e32 v{{[0-9]+}}, vcc, [[ADD1]], v{{[0-9]+}} 70; GFX9: v_add_u32_e32 v{{[0-9]+}}, [[ADD1]], v{{[0-9]+}} 71define amdgpu_kernel void @reassoc_i32_nuw(i32 addrspace(1)* %arg, i32 %x, i32 %y) { 72bb: 73 %tid = tail call i32 @llvm.amdgcn.workitem.id.x() 74 %add1 = add i32 %x, %tid 75 %add2 = add nuw i32 %add1, %y 76 store i32 %add2, i32 addrspace(1)* %arg, align 4 77 ret void 78} 79 80; GCN-LABEL: reassoc_i32_multiuse: 81; GFX8: v_add_u32_e32 [[ADD1:v[0-9]+]], vcc, s{{[0-9]+}}, v{{[0-9]+}} 82; GFX9: v_add_u32_e32 [[ADD1:v[0-9]+]], s{{[0-9]+}}, v{{[0-9]+}} 83; GFX8: v_add_u32_e32 v{{[0-9]+}}, vcc, s{{[0-9]+}}, [[ADD1]] 84; GFX9: v_add_u32_e32 v{{[0-9]+}}, s{{[0-9]+}}, [[ADD1]] 85define amdgpu_kernel void @reassoc_i32_multiuse(i32 addrspace(1)* %arg, i32 %x, i32 %y) { 86bb: 87 %tid = tail call i32 @llvm.amdgcn.workitem.id.x() 88 %add1 = add i32 %x, %tid 89 %add2 = add i32 %add1, %y 90 store volatile i32 %add1, i32 addrspace(1)* %arg, align 4 91 store volatile i32 %add2, i32 addrspace(1)* %arg, align 4 92 ret void 93} 94 95; TODO: This should be reassociated as well, however it is disabled to avoid endless 96; loop since DAGCombiner::ReassociateOps() reverts the reassociation. 97; GCN-LABEL: reassoc_i32_const: 98; GFX8: v_add_u32_e32 [[ADD1:v[0-9]+]], vcc, 42, v{{[0-9]+}} 99; GFX9: v_add_u32_e32 [[ADD1:v[0-9]+]], 42, v{{[0-9]+}} 100; GFX8: v_add_u32_e32 v{{[0-9]+}}, vcc, s{{[0-9]+}}, [[ADD1]] 101; GFX9: v_add_u32_e32 v{{[0-9]+}}, s{{[0-9]+}}, [[ADD1]] 102define amdgpu_kernel void @reassoc_i32_const(i32 addrspace(1)* %arg, i32 %x) { 103bb: 104 %tid = tail call i32 @llvm.amdgcn.workitem.id.x() 105 %add1 = add i32 %tid, 42 106 %add2 = add i32 %add1, %x 107 store volatile i32 %add1, i32 addrspace(1)* %arg, align 4 108 store volatile i32 %add2, i32 addrspace(1)* %arg, align 4 109 ret void 110} 111 112@var = common hidden local_unnamed_addr addrspace(1) global [4 x i32] zeroinitializer, align 4 113 114; GCN-LABEL: reassoc_i32_ga: 115; GCN: s_add_u32 s{{[0-9]+}}, s{{[0-9]+}}, var@rel32@lo+4 116; GCN: s_addc_u32 s{{[0-9]+}}, s{{[0-9]+}}, var@rel32@hi+12 117; GCN: s_endpgm 118define amdgpu_kernel void @reassoc_i32_ga(i64 %x) { 119bb: 120 %tid = tail call i32 @llvm.amdgcn.workitem.id.x() 121 %t64 = zext i32 %tid to i64 122 %add1 = getelementptr [4 x i32], [4 x i32] addrspace(1)* @var, i64 0, i64 %t64 123 %add2 = getelementptr i32, i32 addrspace(1)* %add1, i64 %x 124 store volatile i32 1, i32 addrspace(1)* %add2, align 4 125 ret void 126} 127 128declare i32 @llvm.amdgcn.workitem.id.x() 129declare i32 @llvm.amdgcn.workitem.id.y() 130