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 6define <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 16define <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 26define <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 36define <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 48define <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 58define <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 68define <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 80define <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 93define <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 103define <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 113define <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 126define <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 140define <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 150define <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 160define <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 172define <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 187define <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 197define <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 210define <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 220define <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 232define <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 243define <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 257define <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 268define <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 281define <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 293define <4 x i32> @ule_smax(<4 x i32> %x) { 294; CHECK-LABEL: ule_smax: 295; CHECK: # %bb.0: 296; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 297; CHECK-NEXT: pcmpgtd %xmm1, %xmm0 298; CHECK-NEXT: retq 299 %cmp = icmp ule <4 x i32> %x, <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647> 300 %r = sext <4 x i1> %cmp to <4 x i32> 301 ret <4 x i32> %r 302} 303 304define <4 x i32> @ult_smin(<4 x i32> %x) { 305; CHECK-LABEL: ult_smin: 306; CHECK: # %bb.0: 307; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 308; CHECK-NEXT: pcmpgtd %xmm1, %xmm0 309; CHECK-NEXT: retq 310 %cmp = icmp ult <4 x i32> %x, <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648> 311 %r = sext <4 x i1> %cmp to <4 x i32> 312 ret <4 x i32> %r 313} 314 315define <4 x i32> @uge_smin(<4 x i32> %x) { 316; CHECK-LABEL: uge_smin: 317; CHECK: # %bb.0: 318; CHECK-NEXT: pxor %xmm1, %xmm1 319; CHECK-NEXT: pcmpgtd %xmm0, %xmm1 320; CHECK-NEXT: movdqa %xmm1, %xmm0 321; CHECK-NEXT: retq 322 %cmp = icmp uge <4 x i32> %x, <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648> 323 %r = sext <4 x i1> %cmp to <4 x i32> 324 ret <4 x i32> %r 325} 326 327; Make sure we can efficiently handle ne smin by turning into sgt. 328define <4 x i32> @ne_smin(<4 x i32> %x) { 329; CHECK-LABEL: ne_smin: 330; CHECK: # %bb.0: 331; CHECK-NEXT: pcmpgtd {{.*}}(%rip), %xmm0 332; CHECK-NEXT: retq 333 %cmp = icmp ne <4 x i32> %x, <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648> 334 %r = sext <4 x i1> %cmp to <4 x i32> 335 ret <4 x i32> %r 336} 337 338; Make sure we can efficiently handle ne smax by turning into sgt. We can't fold 339; the constant pool load, but the alternative is a cmpeq+invert which is 3 instructions. 340; The PCMPGT version is two instructions given sufficient register allocation freedom 341; to avoid the last mov to %xmm0 seen here. 342define <4 x i32> @ne_smax(<4 x i32> %x) { 343; CHECK-LABEL: ne_smax: 344; CHECK: # %bb.0: 345; CHECK-NEXT: movdqa {{.*#+}} xmm1 = [2147483647,2147483647,2147483647,2147483647] 346; CHECK-NEXT: pcmpgtd %xmm0, %xmm1 347; CHECK-NEXT: movdqa %xmm1, %xmm0 348; CHECK-NEXT: retq 349 %cmp = icmp ne <4 x i32> %x, <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647> 350 %r = sext <4 x i1> %cmp to <4 x i32> 351 ret <4 x i32> %r 352} 353