1; RUN: llc -march=amdgcn -mcpu=verde -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=FUNC %s 2; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=FUNC %s 3; RUN: llc -march=r600 -mcpu=cypress -verify-machineinstrs < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s 4 5; FUNC-LABEL: {{^}}s_abs_i32: 6; GCN: s_abs_i32 7; GCN: s_add_i32 8 9; EG: MAX_INT 10define void @s_abs_i32(i32 addrspace(1)* %out, i32 %val) nounwind { 11 %neg = sub i32 0, %val 12 %cond = icmp sgt i32 %val, %neg 13 %res = select i1 %cond, i32 %val, i32 %neg 14 %res2 = add i32 %res, 2 15 store i32 %res2, i32 addrspace(1)* %out, align 4 16 ret void 17} 18 19; FUNC-LABEL: {{^}}v_abs_i32: 20; GCN: v_sub_i32_e32 [[NEG:v[0-9]+]], vcc, 0, [[SRC:v[0-9]+]] 21; GCN: v_max_i32_e32 {{v[0-9]+}}, [[NEG]], [[SRC]] 22; GCN: v_add_i32 23 24; EG: MAX_INT 25define void @v_abs_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %src) nounwind { 26 %val = load i32, i32 addrspace(1)* %src, align 4 27 %neg = sub i32 0, %val 28 %cond = icmp sgt i32 %val, %neg 29 %res = select i1 %cond, i32 %val, i32 %neg 30 %res2 = add i32 %res, 2 31 store i32 %res2, i32 addrspace(1)* %out, align 4 32 ret void 33} 34 35; FUNC-LABEL: {{^}}s_abs_v2i32: 36; GCN: s_abs_i32 37; GCN: s_abs_i32 38; GCN: s_add_i32 39; GCN: s_add_i32 40 41; EG: MAX_INT 42; EG: MAX_INT 43define void @s_abs_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> %val) nounwind { 44 %z0 = insertelement <2 x i32> undef, i32 0, i32 0 45 %z1 = insertelement <2 x i32> %z0, i32 0, i32 1 46 %t0 = insertelement <2 x i32> undef, i32 2, i32 0 47 %t1 = insertelement <2 x i32> %t0, i32 2, i32 1 48 %neg = sub <2 x i32> %z1, %val 49 %cond = icmp sgt <2 x i32> %val, %neg 50 %res = select <2 x i1> %cond, <2 x i32> %val, <2 x i32> %neg 51 %res2 = add <2 x i32> %res, %t1 52 store <2 x i32> %res2, <2 x i32> addrspace(1)* %out, align 4 53 ret void 54} 55 56; FUNC-LABEL: {{^}}v_abs_v2i32: 57; GCN-DAG: v_sub_i32_e32 [[NEG0:v[0-9]+]], vcc, 0, [[SRC0:v[0-9]+]] 58; GCN-DAG: v_sub_i32_e32 [[NEG1:v[0-9]+]], vcc, 0, [[SRC1:v[0-9]+]] 59 60; GCN-DAG: v_max_i32_e32 {{v[0-9]+}}, [[NEG0]], [[SRC0]] 61; GCN-DAG: v_max_i32_e32 {{v[0-9]+}}, [[NEG1]], [[SRC1]] 62 63; GCN: v_add_i32 64; GCN: v_add_i32 65 66; EG: MAX_INT 67; EG: MAX_INT 68define void @v_abs_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> addrspace(1)* %src) nounwind { 69 %z0 = insertelement <2 x i32> undef, i32 0, i32 0 70 %z1 = insertelement <2 x i32> %z0, i32 0, i32 1 71 %t0 = insertelement <2 x i32> undef, i32 2, i32 0 72 %t1 = insertelement <2 x i32> %t0, i32 2, i32 1 73 %val = load <2 x i32>, <2 x i32> addrspace(1)* %src, align 4 74 %neg = sub <2 x i32> %z1, %val 75 %cond = icmp sgt <2 x i32> %val, %neg 76 %res = select <2 x i1> %cond, <2 x i32> %val, <2 x i32> %neg 77 %res2 = add <2 x i32> %res, %t1 78 store <2 x i32> %res2, <2 x i32> addrspace(1)* %out, align 4 79 ret void 80} 81 82; FUNC-LABEL: {{^}}s_abs_v4i32: 83; TODO: this should use s_abs_i32 84; GCN: s_abs_i32 85; GCN: s_abs_i32 86; GCN: s_abs_i32 87; GCN: s_abs_i32 88 89; GCN: s_add_i32 90; GCN: s_add_i32 91; GCN: s_add_i32 92; GCN: s_add_i32 93 94; EG: MAX_INT 95; EG: MAX_INT 96; EG: MAX_INT 97; EG: MAX_INT 98define void @s_abs_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> %val) nounwind { 99 %z0 = insertelement <4 x i32> undef, i32 0, i32 0 100 %z1 = insertelement <4 x i32> %z0, i32 0, i32 1 101 %z2 = insertelement <4 x i32> %z1, i32 0, i32 2 102 %z3 = insertelement <4 x i32> %z2, i32 0, i32 3 103 %t0 = insertelement <4 x i32> undef, i32 2, i32 0 104 %t1 = insertelement <4 x i32> %t0, i32 2, i32 1 105 %t2 = insertelement <4 x i32> %t1, i32 2, i32 2 106 %t3 = insertelement <4 x i32> %t2, i32 2, i32 3 107 %neg = sub <4 x i32> %z3, %val 108 %cond = icmp sgt <4 x i32> %val, %neg 109 %res = select <4 x i1> %cond, <4 x i32> %val, <4 x i32> %neg 110 %res2 = add <4 x i32> %res, %t3 111 store <4 x i32> %res2, <4 x i32> addrspace(1)* %out, align 4 112 ret void 113} 114 115; FUNC-LABEL: {{^}}v_abs_v4i32: 116; GCN-DAG: v_sub_i32_e32 [[NEG0:v[0-9]+]], vcc, 0, [[SRC0:v[0-9]+]] 117; GCN-DAG: v_sub_i32_e32 [[NEG1:v[0-9]+]], vcc, 0, [[SRC1:v[0-9]+]] 118; GCN-DAG: v_sub_i32_e32 [[NEG2:v[0-9]+]], vcc, 0, [[SRC2:v[0-9]+]] 119; GCN-DAG: v_sub_i32_e32 [[NEG3:v[0-9]+]], vcc, 0, [[SRC3:v[0-9]+]] 120 121; GCN-DAG: v_max_i32_e32 {{v[0-9]+}}, [[NEG0]], [[SRC0]] 122; GCN-DAG: v_max_i32_e32 {{v[0-9]+}}, [[NEG1]], [[SRC1]] 123; GCN-DAG: v_max_i32_e32 {{v[0-9]+}}, [[NEG2]], [[SRC2]] 124; GCN-DAG: v_max_i32_e32 {{v[0-9]+}}, [[NEG3]], [[SRC3]] 125 126; GCN: v_add_i32 127; GCN: v_add_i32 128; GCN: v_add_i32 129; GCN: v_add_i32 130 131; EG: MAX_INT 132; EG: MAX_INT 133; EG: MAX_INT 134; EG: MAX_INT 135define void @v_abs_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> addrspace(1)* %src) nounwind { 136 %z0 = insertelement <4 x i32> undef, i32 0, i32 0 137 %z1 = insertelement <4 x i32> %z0, i32 0, i32 1 138 %z2 = insertelement <4 x i32> %z1, i32 0, i32 2 139 %z3 = insertelement <4 x i32> %z2, i32 0, i32 3 140 %t0 = insertelement <4 x i32> undef, i32 2, i32 0 141 %t1 = insertelement <4 x i32> %t0, i32 2, i32 1 142 %t2 = insertelement <4 x i32> %t1, i32 2, i32 2 143 %t3 = insertelement <4 x i32> %t2, i32 2, i32 3 144 %val = load <4 x i32>, <4 x i32> addrspace(1)* %src, align 4 145 %neg = sub <4 x i32> %z3, %val 146 %cond = icmp sgt <4 x i32> %val, %neg 147 %res = select <4 x i1> %cond, <4 x i32> %val, <4 x i32> %neg 148 %res2 = add <4 x i32> %res, %t3 149 store <4 x i32> %res2, <4 x i32> addrspace(1)* %out, align 4 150 ret void 151} 152 153; FUNC-LABEL: {{^}}s_min_max_i32: 154; GCN: s_load_dword [[VAL0:s[0-9]+]] 155; GCN: s_load_dword [[VAL1:s[0-9]+]] 156 157; GCN-DAG: s_min_i32 s{{[0-9]+}}, [[VAL0]], [[VAL1]] 158; GCN-DAG: s_max_i32 s{{[0-9]+}}, [[VAL0]], [[VAL1]] 159define void @s_min_max_i32(i32 addrspace(1)* %out0, i32 addrspace(1)* %out1, i32 %val0, i32 %val1) nounwind { 160 %cond0 = icmp sgt i32 %val0, %val1 161 %sel0 = select i1 %cond0, i32 %val0, i32 %val1 162 %sel1 = select i1 %cond0, i32 %val1, i32 %val0 163 164 store volatile i32 %sel0, i32 addrspace(1)* %out0, align 4 165 store volatile i32 %sel1, i32 addrspace(1)* %out1, align 4 166 ret void 167} 168 169; FUNC-LABEL: {{^}}v_min_max_i32: 170; GCN: buffer_load_dword [[VAL0:v[0-9]+]] 171; GCN: buffer_load_dword [[VAL1:v[0-9]+]] 172 173; GCN-DAG: v_min_i32_e32 v{{[0-9]+}}, [[VAL1]], [[VAL0]] 174; GCN-DAG: v_max_i32_e32 v{{[0-9]+}}, [[VAL1]], [[VAL0]] 175define void @v_min_max_i32(i32 addrspace(1)* %out0, i32 addrspace(1)* %out1, i32 addrspace(1)* %ptr0, i32 addrspace(1)* %ptr1) nounwind { 176 %val0 = load volatile i32, i32 addrspace(1)* %ptr0 177 %val1 = load volatile i32, i32 addrspace(1)* %ptr1 178 179 %cond0 = icmp sgt i32 %val0, %val1 180 %sel0 = select i1 %cond0, i32 %val0, i32 %val1 181 %sel1 = select i1 %cond0, i32 %val1, i32 %val0 182 183 store volatile i32 %sel0, i32 addrspace(1)* %out0, align 4 184 store volatile i32 %sel1, i32 addrspace(1)* %out1, align 4 185 ret void 186} 187 188; FUNC-LABEL: {{^}}s_min_max_v4i32: 189; GCN-DAG: s_min_i32 190; GCN-DAG: s_min_i32 191; GCN-DAG: s_min_i32 192; GCN-DAG: s_min_i32 193; GCN-DAG: s_max_i32 194; GCN-DAG: s_max_i32 195; GCN-DAG: s_max_i32 196; GCN-DAG: s_max_i32 197define void @s_min_max_v4i32(<4 x i32> addrspace(1)* %out0, <4 x i32> addrspace(1)* %out1, <4 x i32> %val0, <4 x i32> %val1) nounwind { 198 %cond0 = icmp sgt <4 x i32> %val0, %val1 199 %sel0 = select <4 x i1> %cond0, <4 x i32> %val0, <4 x i32> %val1 200 %sel1 = select <4 x i1> %cond0, <4 x i32> %val1, <4 x i32> %val0 201 202 store volatile <4 x i32> %sel0, <4 x i32> addrspace(1)* %out0, align 4 203 store volatile <4 x i32> %sel1, <4 x i32> addrspace(1)* %out1, align 4 204 ret void 205} 206 207; FUNC-LABEL: {{^}}v_min_max_i32_user: 208; GCN: v_cmp_gt_i32_e32 209; GCN-DAG: v_cndmask_b32_e32 210; GCN-DAG: v_cndmask_b32_e32 211; GCN-DAG: v_cndmask_b32_e64 v{{[0-9]+}}, 0, 1, vcc 212define void @v_min_max_i32_user(i32 addrspace(1)* %out0, i32 addrspace(1)* %out1, i32 addrspace(1)* %ptr0, i32 addrspace(1)* %ptr1) nounwind { 213 %val0 = load volatile i32, i32 addrspace(1)* %ptr0 214 %val1 = load volatile i32, i32 addrspace(1)* %ptr1 215 216 %cond0 = icmp sgt i32 %val0, %val1 217 %sel0 = select i1 %cond0, i32 %val0, i32 %val1 218 %sel1 = select i1 %cond0, i32 %val1, i32 %val0 219 220 store volatile i32 %sel0, i32 addrspace(1)* %out0, align 4 221 store volatile i32 %sel1, i32 addrspace(1)* %out1, align 4 222 store volatile i1 %cond0, i1 addrspace(1)* undef 223 ret void 224} 225