1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2 ; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s 3 4 ; Test simplifications of vector compares that should simplify to true, false or equality. 5 6 define <4 x i32> @slt_min(<4 x i32> %x) { 7 ; CHECK-LABEL: slt_min: 8 ; CHECK: # %bb.0: 9 ; CHECK-NEXT: xorps %xmm0, %xmm0 10 ; CHECK-NEXT: retq 11 %cmp = icmp slt <4 x i32> %x, <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648> 12 %r = sext <4 x i1> %cmp to <4 x i32> 13 ret <4 x i32> %r 14 } 15 16 define <4 x i32> @sge_min(<4 x i32> %x) { 17 ; CHECK-LABEL: sge_min: 18 ; CHECK: # %bb.0: 19 ; CHECK-NEXT: pcmpeqd %xmm0, %xmm0 20 ; CHECK-NEXT: retq 21 %cmp = icmp sge <4 x i32> %x, <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648> 22 %r = sext <4 x i1> %cmp to <4 x i32> 23 ret <4 x i32> %r 24 } 25 26 define <4 x i32> @sgt_min(<4 x i32> %x) { 27 ; CHECK-LABEL: sgt_min: 28 ; CHECK: # %bb.0: 29 ; CHECK-NEXT: pcmpgtd {{.*}}(%rip), %xmm0 30 ; CHECK-NEXT: retq 31 %cmp = icmp sgt <4 x i32> %x, <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648> 32 %r = sext <4 x i1> %cmp to <4 x i32> 33 ret <4 x i32> %r 34 } 35 36 define <4 x i32> @sle_min(<4 x i32> %x) { 37 ; CHECK-LABEL: sle_min: 38 ; CHECK: # %bb.0: 39 ; CHECK-NEXT: pcmpgtd {{.*}}(%rip), %xmm0 40 ; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 41 ; CHECK-NEXT: pxor %xmm1, %xmm0 42 ; CHECK-NEXT: retq 43 %cmp = icmp sle <4 x i32> %x, <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648> 44 %r = sext <4 x i1> %cmp to <4 x i32> 45 ret <4 x i32> %r 46 } 47 48 define <4 x i32> @sgt_max(<4 x i32> %x) { 49 ; CHECK-LABEL: sgt_max: 50 ; CHECK: # %bb.0: 51 ; CHECK-NEXT: xorps %xmm0, %xmm0 52 ; CHECK-NEXT: retq 53 %cmp = icmp sgt <4 x i32> %x, <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647> 54 %r = sext <4 x i1> %cmp to <4 x i32> 55 ret <4 x i32> %r 56 } 57 58 define <4 x i32> @sle_max(<4 x i32> %x) { 59 ; CHECK-LABEL: sle_max: 60 ; CHECK: # %bb.0: 61 ; CHECK-NEXT: pcmpeqd %xmm0, %xmm0 62 ; CHECK-NEXT: retq 63 %cmp = icmp sle <4 x i32> %x, <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647> 64 %r = sext <4 x i1> %cmp to <4 x i32> 65 ret <4 x i32> %r 66 } 67 68 define <4 x i32> @slt_max(<4 x i32> %x) { 69 ; CHECK-LABEL: slt_max: 70 ; CHECK: # %bb.0: 71 ; CHECK-NEXT: movdqa {{.*#+}} xmm1 = [2147483647,2147483647,2147483647,2147483647] 72 ; CHECK-NEXT: pcmpgtd %xmm0, %xmm1 73 ; CHECK-NEXT: movdqa %xmm1, %xmm0 74 ; CHECK-NEXT: retq 75 %cmp = icmp slt <4 x i32> %x, <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647> 76 %r = sext <4 x i1> %cmp to <4 x i32> 77 ret <4 x i32> %r 78 } 79 80 define <4 x i32> @sge_max(<4 x i32> %x) { 81 ; CHECK-LABEL: sge_max: 82 ; CHECK: # %bb.0: 83 ; CHECK-NEXT: movdqa {{.*#+}} xmm1 = [2147483647,2147483647,2147483647,2147483647] 84 ; CHECK-NEXT: pcmpgtd %xmm0, %xmm1 85 ; CHECK-NEXT: pcmpeqd %xmm0, %xmm0 86 ; CHECK-NEXT: pxor %xmm1, %xmm0 87 ; CHECK-NEXT: retq 88 %cmp = icmp sge <4 x i32> %x, <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647> 89 %r = sext <4 x i1> %cmp to <4 x i32> 90 ret <4 x i32> %r 91 } 92 93 define <4 x i32> @ult_min(<4 x i32> %x) { 94 ; CHECK-LABEL: ult_min: 95 ; CHECK: # %bb.0: 96 ; CHECK-NEXT: xorps %xmm0, %xmm0 97 ; CHECK-NEXT: retq 98 %cmp = icmp ult <4 x i32> %x, zeroinitializer 99 %r = sext <4 x i1> %cmp to <4 x i32> 100 ret <4 x i32> %r 101 } 102 103 define <4 x i32> @uge_min(<4 x i32> %x) { 104 ; CHECK-LABEL: uge_min: 105 ; CHECK: # %bb.0: 106 ; CHECK-NEXT: pcmpeqd %xmm0, %xmm0 107 ; CHECK-NEXT: retq 108 %cmp = icmp uge <4 x i32> %x, zeroinitializer 109 %r = sext <4 x i1> %cmp to <4 x i32> 110 ret <4 x i32> %r 111 } 112 113 define <4 x i32> @ugt_min(<4 x i32> %x) { 114 ; CHECK-LABEL: ugt_min: 115 ; CHECK: # %bb.0: 116 ; CHECK-NEXT: pxor %xmm1, %xmm1 117 ; CHECK-NEXT: pcmpeqd %xmm1, %xmm0 118 ; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 119 ; CHECK-NEXT: pxor %xmm1, %xmm0 120 ; CHECK-NEXT: retq 121 %cmp = icmp ugt <4 x i32> %x, zeroinitializer 122 %r = sext <4 x i1> %cmp to <4 x i32> 123 ret <4 x i32> %r 124 } 125 126 define <4 x i32> @ule_min(<4 x i32> %x) { 127 ; CHECK-LABEL: ule_min: 128 ; CHECK: # %bb.0: 129 ; CHECK-NEXT: movdqa {{.*#+}} xmm1 = [2147483648,2147483648,2147483648,2147483648] 130 ; CHECK-NEXT: pxor %xmm1, %xmm0 131 ; CHECK-NEXT: pcmpgtd %xmm1, %xmm0 132 ; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 133 ; CHECK-NEXT: pxor %xmm1, %xmm0 134 ; CHECK-NEXT: retq 135 %cmp = icmp ule <4 x i32> %x, zeroinitializer 136 %r = sext <4 x i1> %cmp to <4 x i32> 137 ret <4 x i32> %r 138 } 139 140 define <4 x i32> @ugt_max(<4 x i32> %x) { 141 ; CHECK-LABEL: ugt_max: 142 ; CHECK: # %bb.0: 143 ; CHECK-NEXT: xorps %xmm0, %xmm0 144 ; CHECK-NEXT: retq 145 %cmp = icmp ugt <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1> 146 %r = sext <4 x i1> %cmp to <4 x i32> 147 ret <4 x i32> %r 148 } 149 150 define <4 x i32> @ule_max(<4 x i32> %x) { 151 ; CHECK-LABEL: ule_max: 152 ; CHECK: # %bb.0: 153 ; CHECK-NEXT: pcmpeqd %xmm0, %xmm0 154 ; CHECK-NEXT: retq 155 %cmp = icmp ule <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1> 156 %r = sext <4 x i1> %cmp to <4 x i32> 157 ret <4 x i32> %r 158 } 159 160 define <4 x i32> @ult_max(<4 x i32> %x) { 161 ; CHECK-LABEL: ult_max: 162 ; CHECK: # %bb.0: 163 ; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 164 ; CHECK-NEXT: pcmpeqd %xmm1, %xmm0 165 ; CHECK-NEXT: pxor %xmm1, %xmm0 166 ; CHECK-NEXT: retq 167 %cmp = icmp ult <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1> 168 %r = sext <4 x i1> %cmp to <4 x i32> 169 ret <4 x i32> %r 170 } 171 172 define <4 x i32> @uge_max(<4 x i32> %x) { 173 ; CHECK-LABEL: uge_max: 174 ; CHECK: # %bb.0: 175 ; CHECK-NEXT: pcmpeqd %xmm2, %xmm2 176 ; CHECK-NEXT: pxor {{.*}}(%rip), %xmm0 177 ; CHECK-NEXT: movdqa {{.*#+}} xmm1 = [2147483647,2147483647,2147483647,2147483647] 178 ; CHECK-NEXT: pcmpgtd %xmm0, %xmm1 179 ; CHECK-NEXT: pxor %xmm2, %xmm1 180 ; CHECK-NEXT: movdqa %xmm1, %xmm0 181 ; CHECK-NEXT: retq 182 %cmp = icmp uge <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1> 183 %r = sext <4 x i1> %cmp to <4 x i32> 184 ret <4 x i32> %r 185 } 186 187 define <4 x i32> @slt_min_plus1(<4 x i32> %x) { 188 ; CHECK-LABEL: slt_min_plus1: 189 ; CHECK: # %bb.0: 190 ; CHECK-NEXT: pcmpeqd {{.*}}(%rip), %xmm0 191 ; CHECK-NEXT: retq 192 %cmp = icmp slt <4 x i32> %x, <i32 -2147483647, i32 -2147483647, i32 -2147483647, i32 -2147483647> 193 %r = sext <4 x i1> %cmp to <4 x i32> 194 ret <4 x i32> %r 195 } 196 197 define <4 x i32> @sge_min_plus1(<4 x i32> %x) { 198 ; CHECK-LABEL: sge_min_plus1: 199 ; CHECK: # %bb.0: 200 ; CHECK-NEXT: movdqa {{.*#+}} xmm1 = [2147483649,2147483649,2147483649,2147483649] 201 ; CHECK-NEXT: pcmpgtd %xmm0, %xmm1 202 ; CHECK-NEXT: pcmpeqd %xmm0, %xmm0 203 ; CHECK-NEXT: pxor %xmm1, %xmm0 204 ; CHECK-NEXT: retq 205 %cmp = icmp sge <4 x i32> %x, <i32 -2147483647, i32 -2147483647, i32 -2147483647, i32 -2147483647> 206 %r = sext <4 x i1> %cmp to <4 x i32> 207 ret <4 x i32> %r 208 } 209 210 define <4 x i32> @sgt_max_minus1(<4 x i32> %x) { 211 ; CHECK-LABEL: sgt_max_minus1: 212 ; CHECK: # %bb.0: 213 ; CHECK-NEXT: pcmpeqd {{.*}}(%rip), %xmm0 214 ; CHECK-NEXT: retq 215 %cmp = icmp sgt <4 x i32> %x, <i32 2147483646, i32 2147483646, i32 2147483646, i32 2147483646> 216 %r = sext <4 x i1> %cmp to <4 x i32> 217 ret <4 x i32> %r 218 } 219 220 define <4 x i32> @sle_max_minus1(<4 x i32> %x) { 221 ; CHECK-LABEL: sle_max_minus1: 222 ; CHECK: # %bb.0: 223 ; CHECK-NEXT: pcmpgtd {{.*}}(%rip), %xmm0 224 ; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 225 ; CHECK-NEXT: pxor %xmm1, %xmm0 226 ; CHECK-NEXT: retq 227 %cmp = icmp sle <4 x i32> %x, <i32 2147483646, i32 2147483646, i32 2147483646, i32 2147483646> 228 %r = sext <4 x i1> %cmp to <4 x i32> 229 ret <4 x i32> %r 230 } 231 232 define <4 x i32> @ult_one(<4 x i32> %x) { 233 ; CHECK-LABEL: ult_one: 234 ; CHECK: # %bb.0: 235 ; CHECK-NEXT: pxor %xmm1, %xmm1 236 ; CHECK-NEXT: pcmpeqd %xmm1, %xmm0 237 ; CHECK-NEXT: retq 238 %cmp = icmp ult <4 x i32> %x, <i32 1, i32 1, i32 1, i32 1> 239 %r = sext <4 x i1> %cmp to <4 x i32> 240 ret <4 x i32> %r 241 } 242 243 define <4 x i32> @uge_one(<4 x i32> %x) { 244 ; CHECK-LABEL: uge_one: 245 ; CHECK: # %bb.0: 246 ; CHECK-NEXT: pxor {{.*}}(%rip), %xmm0 247 ; CHECK-NEXT: movdqa {{.*#+}} xmm1 = [2147483649,2147483649,2147483649,2147483649] 248 ; CHECK-NEXT: pcmpgtd %xmm0, %xmm1 249 ; CHECK-NEXT: pcmpeqd %xmm0, %xmm0 250 ; CHECK-NEXT: pxor %xmm1, %xmm0 251 ; CHECK-NEXT: retq 252 %cmp = icmp uge <4 x i32> %x, <i32 1, i32 1, i32 1, i32 1> 253 %r = sext <4 x i1> %cmp to <4 x i32> 254 ret <4 x i32> %r 255 } 256 257 define <4 x i32> @ugt_max_minus1(<4 x i32> %x) { 258 ; CHECK-LABEL: ugt_max_minus1: 259 ; CHECK: # %bb.0: 260 ; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 261 ; CHECK-NEXT: pcmpeqd %xmm1, %xmm0 262 ; CHECK-NEXT: retq 263 %cmp = icmp ugt <4 x i32> %x, <i32 -2, i32 -2, i32 -2, i32 -2> 264 %r = sext <4 x i1> %cmp to <4 x i32> 265 ret <4 x i32> %r 266 } 267 268 define <4 x i32> @ule_max_minus1(<4 x i32> %x) { 269 ; CHECK-LABEL: ule_max_minus1: 270 ; CHECK: # %bb.0: 271 ; CHECK-NEXT: pxor {{.*}}(%rip), %xmm0 272 ; CHECK-NEXT: pcmpgtd {{.*}}(%rip), %xmm0 273 ; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 274 ; CHECK-NEXT: pxor %xmm1, %xmm0 275 ; CHECK-NEXT: retq 276 %cmp = icmp ule <4 x i32> %x, <i32 -2, i32 -2, i32 -2, i32 -2> 277 %r = sext <4 x i1> %cmp to <4 x i32> 278 ret <4 x i32> %r 279 } 280 281 define <4 x i32> @ugt_smax(<4 x i32> %x) { 282 ; CHECK-LABEL: ugt_smax: 283 ; CHECK: # %bb.0: 284 ; CHECK-NEXT: pxor %xmm1, %xmm1 285 ; CHECK-NEXT: pcmpgtd %xmm0, %xmm1 286 ; CHECK-NEXT: movdqa %xmm1, %xmm0 287 ; CHECK-NEXT: retq 288 %cmp = icmp ugt <4 x i32> %x, <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647> 289 %r = sext <4 x i1> %cmp to <4 x i32> 290 ret <4 x i32> %r 291 } 292 293 define <4 x i32> @ule_smax(<4 x i32> %x) { 294 ; CHECK-LABEL: ule_smax: 295 ; CHECK: # %bb.0: 296 ; CHECK-NEXT: pxor {{.*}}(%rip), %xmm0 297 ; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 298 ; CHECK-NEXT: pcmpgtd %xmm1, %xmm0 299 ; CHECK-NEXT: pxor %xmm1, %xmm0 300 ; CHECK-NEXT: retq 301 %cmp = icmp ule <4 x i32> %x, <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647> 302 %r = sext <4 x i1> %cmp to <4 x i32> 303 ret <4 x i32> %r 304 } 305 306 define <4 x i32> @ult_smin(<4 x i32> %x) { 307 ; CHECK-LABEL: ult_smin: 308 ; CHECK: # %bb.0: 309 ; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 310 ; CHECK-NEXT: pcmpgtd %xmm1, %xmm0 311 ; CHECK-NEXT: retq 312 %cmp = icmp ult <4 x i32> %x, <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648> 313 %r = sext <4 x i1> %cmp to <4 x i32> 314 ret <4 x i32> %r 315 } 316 317 define <4 x i32> @uge_smin(<4 x i32> %x) { 318 ; CHECK-LABEL: uge_smin: 319 ; CHECK: # %bb.0: 320 ; CHECK-NEXT: pxor {{.*}}(%rip), %xmm0 321 ; CHECK-NEXT: pxor %xmm1, %xmm1 322 ; CHECK-NEXT: pcmpgtd %xmm0, %xmm1 323 ; CHECK-NEXT: pcmpeqd %xmm0, %xmm0 324 ; CHECK-NEXT: pxor %xmm1, %xmm0 325 ; CHECK-NEXT: retq 326 %cmp = icmp uge <4 x i32> %x, <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648> 327 %r = sext <4 x i1> %cmp to <4 x i32> 328 ret <4 x i32> %r 329 } 330 331 ; Make sure we can efficiently handle ne smin by turning into sgt. 332 define <4 x i32> @ne_smin(<4 x i32> %x) { 333 ; CHECK-LABEL: ne_smin: 334 ; CHECK: # %bb.0: 335 ; CHECK-NEXT: pcmpgtd {{.*}}(%rip), %xmm0 336 ; CHECK-NEXT: retq 337 %cmp = icmp ne <4 x i32> %x, <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648> 338 %r = sext <4 x i1> %cmp to <4 x i32> 339 ret <4 x i32> %r 340 } 341 342 ; Make sure we can efficiently handle ne smax by turning into sgt. We can't fold 343 ; the constant pool load, but the alternative is a cmpeq+invert which is 3 instructions. 344 ; The PCMPGT version is two instructions given sufficient register allocation freedom 345 ; to avoid the last mov to %xmm0 seen here. 346 define <4 x i32> @ne_smax(<4 x i32> %x) { 347 ; CHECK-LABEL: ne_smax: 348 ; CHECK: # %bb.0: 349 ; CHECK-NEXT: movdqa {{.*#+}} xmm1 = [2147483647,2147483647,2147483647,2147483647] 350 ; CHECK-NEXT: pcmpgtd %xmm0, %xmm1 351 ; CHECK-NEXT: movdqa %xmm1, %xmm0 352 ; CHECK-NEXT: retq 353 %cmp = icmp ne <4 x i32> %x, <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647> 354 %r = sext <4 x i1> %cmp to <4 x i32> 355 ret <4 x i32> %r 356 } 357