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