1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -slp-vectorizer -mtriple=x86_64-- -S | FileCheck %s --check-prefixes=CHECK,SSE 3; RUN: opt < %s -slp-vectorizer -mtriple=x86_64-- -mattr=avx512vl -S | FileCheck %s --check-prefixes=CHECK,AVX 4 5declare void @use1(i1) 6 7define i1 @logical_and_icmp(<4 x i32> %x) { 8; CHECK-LABEL: @logical_and_icmp( 9; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <4 x i32> [[X:%.*]], zeroinitializer 10; CHECK-NEXT: [[TMP2:%.*]] = freeze <4 x i1> [[TMP1]] 11; CHECK-NEXT: [[TMP3:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP2]]) 12; CHECK-NEXT: ret i1 [[TMP3]] 13; 14 %x0 = extractelement <4 x i32> %x, i32 0 15 %x1 = extractelement <4 x i32> %x, i32 1 16 %x2 = extractelement <4 x i32> %x, i32 2 17 %x3 = extractelement <4 x i32> %x, i32 3 18 %c0 = icmp slt i32 %x0, 0 19 %c1 = icmp slt i32 %x1, 0 20 %c2 = icmp slt i32 %x2, 0 21 %c3 = icmp slt i32 %x3, 0 22 %s1 = select i1 %c0, i1 %c1, i1 false 23 %s2 = select i1 %s1, i1 %c2, i1 false 24 %s3 = select i1 %s2, i1 %c3, i1 false 25 ret i1 %s3 26} 27 28define i1 @logical_or_icmp(<4 x i32> %x, <4 x i32> %y) { 29; CHECK-LABEL: @logical_or_icmp( 30; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <4 x i32> [[X:%.*]], [[Y:%.*]] 31; CHECK-NEXT: [[TMP2:%.*]] = freeze <4 x i1> [[TMP1]] 32; CHECK-NEXT: [[TMP3:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP2]]) 33; CHECK-NEXT: ret i1 [[TMP3]] 34; 35 %x0 = extractelement <4 x i32> %x, i32 0 36 %x1 = extractelement <4 x i32> %x, i32 1 37 %x2 = extractelement <4 x i32> %x, i32 2 38 %x3 = extractelement <4 x i32> %x, i32 3 39 %y0 = extractelement <4 x i32> %y, i32 0 40 %y1 = extractelement <4 x i32> %y, i32 1 41 %y2 = extractelement <4 x i32> %y, i32 2 42 %y3 = extractelement <4 x i32> %y, i32 3 43 %c0 = icmp slt i32 %x0, %y0 44 %c1 = icmp slt i32 %x1, %y1 45 %c2 = icmp slt i32 %x2, %y2 46 %c3 = icmp slt i32 %x3, %y3 47 %s1 = select i1 %c0, i1 true, i1 %c1 48 %s2 = select i1 %s1, i1 true, i1 %c2 49 %s3 = select i1 %s2, i1 true, i1 %c3 50 ret i1 %s3 51} 52 53define i1 @logical_and_fcmp(<4 x float> %x) { 54; CHECK-LABEL: @logical_and_fcmp( 55; CHECK-NEXT: [[TMP1:%.*]] = fcmp olt <4 x float> [[X:%.*]], zeroinitializer 56; CHECK-NEXT: [[TMP2:%.*]] = freeze <4 x i1> [[TMP1]] 57; CHECK-NEXT: [[TMP3:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP2]]) 58; CHECK-NEXT: ret i1 [[TMP3]] 59; 60 %x0 = extractelement <4 x float> %x, i32 0 61 %x1 = extractelement <4 x float> %x, i32 1 62 %x2 = extractelement <4 x float> %x, i32 2 63 %x3 = extractelement <4 x float> %x, i32 3 64 %c0 = fcmp olt float %x0, 0.0 65 %c1 = fcmp olt float %x1, 0.0 66 %c2 = fcmp olt float %x2, 0.0 67 %c3 = fcmp olt float %x3, 0.0 68 %s1 = select i1 %c0, i1 %c1, i1 false 69 %s2 = select i1 %s1, i1 %c2, i1 false 70 %s3 = select i1 %s2, i1 %c3, i1 false 71 ret i1 %s3 72} 73 74define i1 @logical_or_fcmp(<4 x float> %x) { 75; CHECK-LABEL: @logical_or_fcmp( 76; CHECK-NEXT: [[TMP1:%.*]] = fcmp olt <4 x float> [[X:%.*]], zeroinitializer 77; CHECK-NEXT: [[TMP2:%.*]] = freeze <4 x i1> [[TMP1]] 78; CHECK-NEXT: [[TMP3:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP2]]) 79; CHECK-NEXT: ret i1 [[TMP3]] 80; 81 %x0 = extractelement <4 x float> %x, i32 0 82 %x1 = extractelement <4 x float> %x, i32 1 83 %x2 = extractelement <4 x float> %x, i32 2 84 %x3 = extractelement <4 x float> %x, i32 3 85 %c0 = fcmp olt float %x0, 0.0 86 %c1 = fcmp olt float %x1, 0.0 87 %c2 = fcmp olt float %x2, 0.0 88 %c3 = fcmp olt float %x3, 0.0 89 %s1 = select i1 %c0, i1 true, i1 %c1 90 %s2 = select i1 %s1, i1 true, i1 %c2 91 %s3 = select i1 %s2, i1 true, i1 %c3 92 ret i1 %s3 93} 94 95define i1 @logical_and_icmp_diff_preds(<4 x i32> %x) { 96; SSE-LABEL: @logical_and_icmp_diff_preds( 97; SSE-NEXT: [[X0:%.*]] = extractelement <4 x i32> [[X:%.*]], i32 0 98; SSE-NEXT: [[X1:%.*]] = extractelement <4 x i32> [[X]], i32 1 99; SSE-NEXT: [[X2:%.*]] = extractelement <4 x i32> [[X]], i32 2 100; SSE-NEXT: [[X3:%.*]] = extractelement <4 x i32> [[X]], i32 3 101; SSE-NEXT: [[C0:%.*]] = icmp ult i32 [[X0]], 0 102; SSE-NEXT: [[C2:%.*]] = icmp sgt i32 [[X2]], 0 103; SSE-NEXT: [[TMP1:%.*]] = insertelement <2 x i32> poison, i32 [[X3]], i32 0 104; SSE-NEXT: [[TMP2:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[X1]], i32 1 105; SSE-NEXT: [[TMP3:%.*]] = icmp slt <2 x i32> [[TMP2]], zeroinitializer 106; SSE-NEXT: [[TMP4:%.*]] = extractelement <2 x i1> [[TMP3]], i32 1 107; SSE-NEXT: [[S1:%.*]] = select i1 [[C0]], i1 [[TMP4]], i1 false 108; SSE-NEXT: [[S2:%.*]] = select i1 [[S1]], i1 [[C2]], i1 false 109; SSE-NEXT: [[TMP5:%.*]] = extractelement <2 x i1> [[TMP3]], i32 0 110; SSE-NEXT: [[S3:%.*]] = select i1 [[S2]], i1 [[TMP5]], i1 false 111; SSE-NEXT: ret i1 [[S3]] 112; 113; AVX-LABEL: @logical_and_icmp_diff_preds( 114; AVX-NEXT: [[X0:%.*]] = extractelement <4 x i32> [[X:%.*]], i32 0 115; AVX-NEXT: [[X1:%.*]] = extractelement <4 x i32> [[X]], i32 1 116; AVX-NEXT: [[X2:%.*]] = extractelement <4 x i32> [[X]], i32 2 117; AVX-NEXT: [[X3:%.*]] = extractelement <4 x i32> [[X]], i32 3 118; AVX-NEXT: [[C0:%.*]] = icmp ult i32 [[X0]], 0 119; AVX-NEXT: [[C1:%.*]] = icmp slt i32 [[X1]], 0 120; AVX-NEXT: [[C2:%.*]] = icmp sgt i32 [[X2]], 0 121; AVX-NEXT: [[C3:%.*]] = icmp slt i32 [[X3]], 0 122; AVX-NEXT: [[S1:%.*]] = select i1 [[C0]], i1 [[C1]], i1 false 123; AVX-NEXT: [[S2:%.*]] = select i1 [[S1]], i1 [[C2]], i1 false 124; AVX-NEXT: [[S3:%.*]] = select i1 [[S2]], i1 [[C3]], i1 false 125; AVX-NEXT: ret i1 [[S3]] 126; 127 %x0 = extractelement <4 x i32> %x, i32 0 128 %x1 = extractelement <4 x i32> %x, i32 1 129 %x2 = extractelement <4 x i32> %x, i32 2 130 %x3 = extractelement <4 x i32> %x, i32 3 131 %c0 = icmp ult i32 %x0, 0 132 %c1 = icmp slt i32 %x1, 0 133 %c2 = icmp sgt i32 %x2, 0 134 %c3 = icmp slt i32 %x3, 0 135 %s1 = select i1 %c0, i1 %c1, i1 false 136 %s2 = select i1 %s1, i1 %c2, i1 false 137 %s3 = select i1 %s2, i1 %c3, i1 false 138 ret i1 %s3 139} 140 141define i1 @logical_and_icmp_diff_const(<4 x i32> %x) { 142; CHECK-LABEL: @logical_and_icmp_diff_const( 143; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i32> [[X:%.*]], <i32 0, i32 1, i32 2, i32 3> 144; CHECK-NEXT: [[TMP2:%.*]] = freeze <4 x i1> [[TMP1]] 145; CHECK-NEXT: [[TMP3:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP2]]) 146; CHECK-NEXT: ret i1 [[TMP3]] 147; 148 %x0 = extractelement <4 x i32> %x, i32 0 149 %x1 = extractelement <4 x i32> %x, i32 1 150 %x2 = extractelement <4 x i32> %x, i32 2 151 %x3 = extractelement <4 x i32> %x, i32 3 152 %c0 = icmp sgt i32 %x0, 0 153 %c1 = icmp sgt i32 %x1, 1 154 %c2 = icmp sgt i32 %x2, 2 155 %c3 = icmp sgt i32 %x3, 3 156 %s1 = select i1 %c0, i1 %c1, i1 false 157 %s2 = select i1 %s1, i1 %c2, i1 false 158 %s3 = select i1 %s2, i1 %c3, i1 false 159 ret i1 %s3 160} 161 162define i1 @mixed_logical_icmp(<4 x i32> %x) { 163; CHECK-LABEL: @mixed_logical_icmp( 164; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i32> [[X:%.*]], zeroinitializer 165; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x i1> [[TMP1]], i32 0 166; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x i1> [[TMP1]], i32 1 167; CHECK-NEXT: [[S1:%.*]] = select i1 [[TMP2]], i1 [[TMP3]], i1 false 168; CHECK-NEXT: [[TMP4:%.*]] = extractelement <4 x i1> [[TMP1]], i32 2 169; CHECK-NEXT: [[S2:%.*]] = select i1 [[S1]], i1 true, i1 [[TMP4]] 170; CHECK-NEXT: [[TMP5:%.*]] = extractelement <4 x i1> [[TMP1]], i32 3 171; CHECK-NEXT: [[S3:%.*]] = select i1 [[S2]], i1 [[TMP5]], i1 false 172; CHECK-NEXT: ret i1 [[S3]] 173; 174 %x0 = extractelement <4 x i32> %x, i32 0 175 %x1 = extractelement <4 x i32> %x, i32 1 176 %x2 = extractelement <4 x i32> %x, i32 2 177 %x3 = extractelement <4 x i32> %x, i32 3 178 %c0 = icmp sgt i32 %x0, 0 179 %c1 = icmp sgt i32 %x1, 0 180 %c2 = icmp sgt i32 %x2, 0 181 %c3 = icmp sgt i32 %x3, 0 182 %s1 = select i1 %c0, i1 %c1, i1 false 183 %s2 = select i1 %s1, i1 true, i1 %c2 184 %s3 = select i1 %s2, i1 %c3, i1 false 185 ret i1 %s3 186} 187 188define i1 @logical_and_icmp_subvec(<4 x i32> %x) { 189; SSE-LABEL: @logical_and_icmp_subvec( 190; SSE-NEXT: [[X0:%.*]] = extractelement <4 x i32> [[X:%.*]], i32 0 191; SSE-NEXT: [[X1:%.*]] = extractelement <4 x i32> [[X]], i32 1 192; SSE-NEXT: [[X2:%.*]] = extractelement <4 x i32> [[X]], i32 2 193; SSE-NEXT: [[TMP1:%.*]] = insertelement <2 x i32> poison, i32 [[X1]], i32 0 194; SSE-NEXT: [[TMP2:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[X0]], i32 1 195; SSE-NEXT: [[TMP3:%.*]] = icmp slt <2 x i32> [[TMP2]], zeroinitializer 196; SSE-NEXT: [[C2:%.*]] = icmp slt i32 [[X2]], 0 197; SSE-NEXT: [[TMP4:%.*]] = extractelement <2 x i1> [[TMP3]], i32 0 198; SSE-NEXT: [[TMP5:%.*]] = extractelement <2 x i1> [[TMP3]], i32 1 199; SSE-NEXT: [[S1:%.*]] = select i1 [[TMP5]], i1 [[TMP4]], i1 false 200; SSE-NEXT: [[S2:%.*]] = select i1 [[S1]], i1 [[C2]], i1 false 201; SSE-NEXT: ret i1 [[S2]] 202; 203; AVX-LABEL: @logical_and_icmp_subvec( 204; AVX-NEXT: [[X0:%.*]] = extractelement <4 x i32> [[X:%.*]], i32 0 205; AVX-NEXT: [[X1:%.*]] = extractelement <4 x i32> [[X]], i32 1 206; AVX-NEXT: [[X2:%.*]] = extractelement <4 x i32> [[X]], i32 2 207; AVX-NEXT: [[C0:%.*]] = icmp slt i32 [[X0]], 0 208; AVX-NEXT: [[C1:%.*]] = icmp slt i32 [[X1]], 0 209; AVX-NEXT: [[C2:%.*]] = icmp slt i32 [[X2]], 0 210; AVX-NEXT: [[S1:%.*]] = select i1 [[C0]], i1 [[C1]], i1 false 211; AVX-NEXT: [[S2:%.*]] = select i1 [[S1]], i1 [[C2]], i1 false 212; AVX-NEXT: ret i1 [[S2]] 213; 214 %x0 = extractelement <4 x i32> %x, i32 0 215 %x1 = extractelement <4 x i32> %x, i32 1 216 %x2 = extractelement <4 x i32> %x, i32 2 217 %c0 = icmp slt i32 %x0, 0 218 %c1 = icmp slt i32 %x1, 0 219 %c2 = icmp slt i32 %x2, 0 220 %s1 = select i1 %c0, i1 %c1, i1 false 221 %s2 = select i1 %s1, i1 %c2, i1 false 222 ret i1 %s2 223} 224 225; TODO: This is better than all-scalar and still safe, 226; but we want this to be 2 reductions with glue 227; logic...or a wide reduction? 228 229define i1 @logical_and_icmp_clamp(<4 x i32> %x) { 230; CHECK-LABEL: @logical_and_icmp_clamp( 231; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <4 x i32> [[X:%.*]], <i32 42, i32 42, i32 42, i32 42> 232; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt <4 x i32> [[X]], <i32 17, i32 17, i32 17, i32 17> 233; CHECK-NEXT: [[TMP3:%.*]] = freeze <4 x i1> [[TMP2]] 234; CHECK-NEXT: [[TMP4:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP3]]) 235; CHECK-NEXT: [[TMP5:%.*]] = freeze <4 x i1> [[TMP1]] 236; CHECK-NEXT: [[TMP6:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP5]]) 237; CHECK-NEXT: [[OP_RDX:%.*]] = select i1 [[TMP4]], i1 [[TMP6]], i1 false 238; CHECK-NEXT: ret i1 [[OP_RDX]] 239; 240 %x0 = extractelement <4 x i32> %x, i32 0 241 %x1 = extractelement <4 x i32> %x, i32 1 242 %x2 = extractelement <4 x i32> %x, i32 2 243 %x3 = extractelement <4 x i32> %x, i32 3 244 %c0 = icmp slt i32 %x0, 42 245 %c1 = icmp slt i32 %x1, 42 246 %c2 = icmp slt i32 %x2, 42 247 %c3 = icmp slt i32 %x3, 42 248 %d0 = icmp sgt i32 %x0, 17 249 %d1 = icmp sgt i32 %x1, 17 250 %d2 = icmp sgt i32 %x2, 17 251 %d3 = icmp sgt i32 %x3, 17 252 %s1 = select i1 %c0, i1 %c1, i1 false 253 %s2 = select i1 %s1, i1 %c2, i1 false 254 %s3 = select i1 %s2, i1 %c3, i1 false 255 %s4 = select i1 %s3, i1 %d0, i1 false 256 %s5 = select i1 %s4, i1 %d1, i1 false 257 %s6 = select i1 %s5, i1 %d2, i1 false 258 %s7 = select i1 %s6, i1 %d3, i1 false 259 ret i1 %s7 260} 261 262define i1 @logical_and_icmp_clamp_extra_use_cmp(<4 x i32> %x) { 263; CHECK-LABEL: @logical_and_icmp_clamp_extra_use_cmp( 264; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <4 x i32> [[X:%.*]], <i32 42, i32 42, i32 42, i32 42> 265; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x i1> [[TMP1]], i32 2 266; CHECK-NEXT: call void @use1(i1 [[TMP2]]) 267; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt <4 x i32> [[X]], <i32 17, i32 17, i32 17, i32 17> 268; CHECK-NEXT: [[TMP4:%.*]] = freeze <4 x i1> [[TMP3]] 269; CHECK-NEXT: [[TMP5:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP4]]) 270; CHECK-NEXT: [[TMP6:%.*]] = freeze <4 x i1> [[TMP1]] 271; CHECK-NEXT: [[TMP7:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP6]]) 272; CHECK-NEXT: [[OP_RDX:%.*]] = select i1 [[TMP5]], i1 [[TMP7]], i1 false 273; CHECK-NEXT: ret i1 [[OP_RDX]] 274; 275 %x0 = extractelement <4 x i32> %x, i32 0 276 %x1 = extractelement <4 x i32> %x, i32 1 277 %x2 = extractelement <4 x i32> %x, i32 2 278 %x3 = extractelement <4 x i32> %x, i32 3 279 %c0 = icmp slt i32 %x0, 42 280 %c1 = icmp slt i32 %x1, 42 281 %c2 = icmp slt i32 %x2, 42 282 call void @use1(i1 %c2) 283 %c3 = icmp slt i32 %x3, 42 284 %d0 = icmp sgt i32 %x0, 17 285 %d1 = icmp sgt i32 %x1, 17 286 %d2 = icmp sgt i32 %x2, 17 287 %d3 = icmp sgt i32 %x3, 17 288 %s1 = select i1 %c0, i1 %c1, i1 false 289 %s2 = select i1 %s1, i1 %c2, i1 false 290 %s3 = select i1 %s2, i1 %c3, i1 false 291 %s4 = select i1 %s3, i1 %d0, i1 false 292 %s5 = select i1 %s4, i1 %d1, i1 false 293 %s6 = select i1 %s5, i1 %d2, i1 false 294 %s7 = select i1 %s6, i1 %d3, i1 false 295 ret i1 %s7 296} 297 298define i1 @logical_and_icmp_clamp_extra_use_select(<4 x i32> %x) { 299; CHECK-LABEL: @logical_and_icmp_clamp_extra_use_select( 300; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <4 x i32> [[X:%.*]], <i32 42, i32 42, i32 42, i32 42> 301; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt <4 x i32> [[X]], <i32 17, i32 17, i32 17, i32 17> 302; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x i1> [[TMP1]], i32 0 303; CHECK-NEXT: [[TMP4:%.*]] = extractelement <4 x i1> [[TMP1]], i32 1 304; CHECK-NEXT: [[S1:%.*]] = select i1 [[TMP3]], i1 [[TMP4]], i1 false 305; CHECK-NEXT: [[TMP5:%.*]] = extractelement <4 x i1> [[TMP1]], i32 2 306; CHECK-NEXT: [[S2:%.*]] = select i1 [[S1]], i1 [[TMP5]], i1 false 307; CHECK-NEXT: call void @use1(i1 [[S2]]) 308; CHECK-NEXT: [[TMP6:%.*]] = freeze <4 x i1> [[TMP2]] 309; CHECK-NEXT: [[TMP7:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP6]]) 310; CHECK-NEXT: [[TMP8:%.*]] = extractelement <4 x i1> [[TMP1]], i32 3 311; CHECK-NEXT: [[OP_RDX:%.*]] = select i1 [[TMP7]], i1 [[TMP8]], i1 false 312; CHECK-NEXT: [[OP_RDX1:%.*]] = select i1 [[OP_RDX]], i1 [[S2]], i1 false 313; CHECK-NEXT: ret i1 [[OP_RDX1]] 314; 315 %x0 = extractelement <4 x i32> %x, i32 0 316 %x1 = extractelement <4 x i32> %x, i32 1 317 %x2 = extractelement <4 x i32> %x, i32 2 318 %x3 = extractelement <4 x i32> %x, i32 3 319 %c0 = icmp slt i32 %x0, 42 320 %c1 = icmp slt i32 %x1, 42 321 %c2 = icmp slt i32 %x2, 42 322 %c3 = icmp slt i32 %x3, 42 323 %d0 = icmp sgt i32 %x0, 17 324 %d1 = icmp sgt i32 %x1, 17 325 %d2 = icmp sgt i32 %x2, 17 326 %d3 = icmp sgt i32 %x3, 17 327 %s1 = select i1 %c0, i1 %c1, i1 false 328 %s2 = select i1 %s1, i1 %c2, i1 false 329 call void @use1(i1 %s2) 330 %s3 = select i1 %s2, i1 %c3, i1 false 331 %s4 = select i1 %s3, i1 %d0, i1 false 332 %s5 = select i1 %s4, i1 %d1, i1 false 333 %s6 = select i1 %s5, i1 %d2, i1 false 334 %s7 = select i1 %s6, i1 %d3, i1 false 335 ret i1 %s7 336} 337 338define i1 @logical_and_icmp_clamp_v8i32(<8 x i32> %x, <8 x i32> %y) { 339; CHECK-LABEL: @logical_and_icmp_clamp_v8i32( 340; CHECK-NEXT: [[X0:%.*]] = extractelement <8 x i32> [[X:%.*]], i32 0 341; CHECK-NEXT: [[X1:%.*]] = extractelement <8 x i32> [[X]], i32 1 342; CHECK-NEXT: [[X2:%.*]] = extractelement <8 x i32> [[X]], i32 2 343; CHECK-NEXT: [[X3:%.*]] = extractelement <8 x i32> [[X]], i32 3 344; CHECK-NEXT: [[Y0:%.*]] = extractelement <8 x i32> [[Y:%.*]], i32 0 345; CHECK-NEXT: [[Y1:%.*]] = extractelement <8 x i32> [[Y]], i32 1 346; CHECK-NEXT: [[Y2:%.*]] = extractelement <8 x i32> [[Y]], i32 2 347; CHECK-NEXT: [[Y3:%.*]] = extractelement <8 x i32> [[Y]], i32 3 348; CHECK-NEXT: [[TMP1:%.*]] = insertelement <8 x i32> poison, i32 [[X1]], i32 0 349; CHECK-NEXT: [[TMP2:%.*]] = insertelement <8 x i32> [[TMP1]], i32 [[X0]], i32 1 350; CHECK-NEXT: [[TMP3:%.*]] = insertelement <8 x i32> [[TMP2]], i32 [[X2]], i32 2 351; CHECK-NEXT: [[TMP4:%.*]] = insertelement <8 x i32> [[TMP3]], i32 [[X3]], i32 3 352; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <8 x i32> [[TMP4]], <8 x i32> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 1, i32 0, i32 2, i32 3> 353; CHECK-NEXT: [[TMP5:%.*]] = insertelement <8 x i32> <i32 42, i32 42, i32 42, i32 42, i32 poison, i32 poison, i32 poison, i32 poison>, i32 [[Y0]], i32 4 354; CHECK-NEXT: [[TMP6:%.*]] = insertelement <8 x i32> [[TMP5]], i32 [[Y1]], i32 5 355; CHECK-NEXT: [[TMP7:%.*]] = insertelement <8 x i32> [[TMP6]], i32 [[Y2]], i32 6 356; CHECK-NEXT: [[TMP8:%.*]] = insertelement <8 x i32> [[TMP7]], i32 [[Y3]], i32 7 357; CHECK-NEXT: [[TMP9:%.*]] = icmp slt <8 x i32> [[SHUFFLE]], [[TMP8]] 358; CHECK-NEXT: [[TMP10:%.*]] = freeze <8 x i1> [[TMP9]] 359; CHECK-NEXT: [[TMP11:%.*]] = call i1 @llvm.vector.reduce.and.v8i1(<8 x i1> [[TMP10]]) 360; CHECK-NEXT: ret i1 [[TMP11]] 361; 362 %x0 = extractelement <8 x i32> %x, i32 0 363 %x1 = extractelement <8 x i32> %x, i32 1 364 %x2 = extractelement <8 x i32> %x, i32 2 365 %x3 = extractelement <8 x i32> %x, i32 3 366 %y0 = extractelement <8 x i32> %y, i32 0 367 %y1 = extractelement <8 x i32> %y, i32 1 368 %y2 = extractelement <8 x i32> %y, i32 2 369 %y3 = extractelement <8 x i32> %y, i32 3 370 %c0 = icmp slt i32 %x0, 42 371 %c1 = icmp slt i32 %x1, 42 372 %c2 = icmp slt i32 %x2, 42 373 %c3 = icmp slt i32 %x3, 42 374 %d0 = icmp slt i32 %x0, %y0 375 %d1 = icmp slt i32 %x1, %y1 376 %d2 = icmp slt i32 %x2, %y2 377 %d3 = icmp slt i32 %x3, %y3 378 %s1 = select i1 %c0, i1 %c1, i1 false 379 %s2 = select i1 %s1, i1 %c2, i1 false 380 %s3 = select i1 %s2, i1 %c3, i1 false 381 %s4 = select i1 %s3, i1 %d0, i1 false 382 %s5 = select i1 %s4, i1 %d1, i1 false 383 %s6 = select i1 %s5, i1 %d2, i1 false 384 %s7 = select i1 %s6, i1 %d3, i1 false 385 ret i1 %s7 386} 387 388define i1 @logical_and_icmp_clamp_partial(<4 x i32> %x) { 389; SSE-LABEL: @logical_and_icmp_clamp_partial( 390; SSE-NEXT: [[TMP1:%.*]] = extractelement <4 x i32> [[X:%.*]], i32 2 391; SSE-NEXT: [[TMP2:%.*]] = extractelement <4 x i32> [[X]], i32 1 392; SSE-NEXT: [[TMP3:%.*]] = extractelement <4 x i32> [[X]], i32 0 393; SSE-NEXT: [[TMP4:%.*]] = insertelement <2 x i32> poison, i32 [[TMP2]], i32 0 394; SSE-NEXT: [[TMP5:%.*]] = insertelement <2 x i32> [[TMP4]], i32 [[TMP3]], i32 1 395; SSE-NEXT: [[TMP6:%.*]] = icmp slt <2 x i32> [[TMP5]], <i32 42, i32 42> 396; SSE-NEXT: [[C2:%.*]] = icmp slt i32 [[TMP1]], 42 397; SSE-NEXT: [[TMP7:%.*]] = icmp sgt <4 x i32> [[X]], <i32 17, i32 17, i32 17, i32 17> 398; SSE-NEXT: [[TMP8:%.*]] = freeze <4 x i1> [[TMP7]] 399; SSE-NEXT: [[TMP9:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP8]]) 400; SSE-NEXT: [[TMP10:%.*]] = extractelement <2 x i1> [[TMP6]], i32 0 401; SSE-NEXT: [[OP_RDX:%.*]] = select i1 [[TMP9]], i1 [[TMP10]], i1 false 402; SSE-NEXT: [[TMP11:%.*]] = extractelement <2 x i1> [[TMP6]], i32 1 403; SSE-NEXT: [[OP_RDX1:%.*]] = select i1 [[OP_RDX]], i1 [[TMP11]], i1 false 404; SSE-NEXT: [[OP_RDX2:%.*]] = select i1 [[OP_RDX1]], i1 [[C2]], i1 false 405; SSE-NEXT: ret i1 [[OP_RDX2]] 406; 407; AVX-LABEL: @logical_and_icmp_clamp_partial( 408; AVX-NEXT: [[TMP1:%.*]] = extractelement <4 x i32> [[X:%.*]], i32 2 409; AVX-NEXT: [[TMP2:%.*]] = extractelement <4 x i32> [[X]], i32 1 410; AVX-NEXT: [[TMP3:%.*]] = extractelement <4 x i32> [[X]], i32 0 411; AVX-NEXT: [[C0:%.*]] = icmp slt i32 [[TMP3]], 42 412; AVX-NEXT: [[C1:%.*]] = icmp slt i32 [[TMP2]], 42 413; AVX-NEXT: [[C2:%.*]] = icmp slt i32 [[TMP1]], 42 414; AVX-NEXT: [[TMP4:%.*]] = icmp sgt <4 x i32> [[X]], <i32 17, i32 17, i32 17, i32 17> 415; AVX-NEXT: [[TMP5:%.*]] = freeze <4 x i1> [[TMP4]] 416; AVX-NEXT: [[TMP6:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP5]]) 417; AVX-NEXT: [[OP_RDX:%.*]] = select i1 [[TMP6]], i1 [[C1]], i1 false 418; AVX-NEXT: [[OP_RDX1:%.*]] = select i1 [[OP_RDX]], i1 [[C0]], i1 false 419; AVX-NEXT: [[OP_RDX2:%.*]] = select i1 [[OP_RDX1]], i1 [[C2]], i1 false 420; AVX-NEXT: ret i1 [[OP_RDX2]] 421; 422 %x0 = extractelement <4 x i32> %x, i32 0 423 %x1 = extractelement <4 x i32> %x, i32 1 424 %x2 = extractelement <4 x i32> %x, i32 2 425 %x3 = extractelement <4 x i32> %x, i32 3 426 %c0 = icmp slt i32 %x0, 42 427 %c1 = icmp slt i32 %x1, 42 428 %c2 = icmp slt i32 %x2, 42 429 ; remove an element from the previous test 430 %d0 = icmp sgt i32 %x0, 17 431 %d1 = icmp sgt i32 %x1, 17 432 %d2 = icmp sgt i32 %x2, 17 433 %d3 = icmp sgt i32 %x3, 17 434 %s1 = select i1 %c0, i1 %c1, i1 false 435 %s2 = select i1 %s1, i1 %c2, i1 false 436 ; remove an element from the previous test 437 %s4 = select i1 %s2, i1 %d0, i1 false 438 %s5 = select i1 %s4, i1 %d1, i1 false 439 %s6 = select i1 %s5, i1 %d2, i1 false 440 %s7 = select i1 %s6, i1 %d3, i1 false 441 ret i1 %s7 442} 443 444define i1 @logical_and_icmp_clamp_pred_diff(<4 x i32> %x) { 445; CHECK-LABEL: @logical_and_icmp_clamp_pred_diff( 446; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <4 x i32> [[X:%.*]], <i32 42, i32 42, i32 42, i32 42> 447; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <4 x i32> [[X]], <i32 42, i32 42, i32 42, i32 42> 448; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <4 x i1> [[TMP1]], <4 x i1> [[TMP2]], <4 x i32> <i32 0, i32 1, i32 2, i32 7> 449; CHECK-NEXT: [[TMP4:%.*]] = icmp sgt <4 x i32> [[X]], <i32 17, i32 17, i32 17, i32 17> 450; CHECK-NEXT: [[TMP5:%.*]] = freeze <4 x i1> [[TMP4]] 451; CHECK-NEXT: [[TMP6:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP5]]) 452; CHECK-NEXT: [[TMP7:%.*]] = freeze <4 x i1> [[TMP3]] 453; CHECK-NEXT: [[TMP8:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP7]]) 454; CHECK-NEXT: [[OP_RDX:%.*]] = select i1 [[TMP6]], i1 [[TMP8]], i1 false 455; CHECK-NEXT: ret i1 [[OP_RDX]] 456; 457 %x0 = extractelement <4 x i32> %x, i32 0 458 %x1 = extractelement <4 x i32> %x, i32 1 459 %x2 = extractelement <4 x i32> %x, i32 2 460 %x3 = extractelement <4 x i32> %x, i32 3 461 %c0 = icmp slt i32 %x0, 42 462 %c1 = icmp slt i32 %x1, 42 463 %c2 = icmp slt i32 %x2, 42 464 %c3 = icmp ult i32 %x3, 42 ; predicate changed 465 %d0 = icmp sgt i32 %x0, 17 466 %d1 = icmp sgt i32 %x1, 17 467 %d2 = icmp sgt i32 %x2, 17 468 %d3 = icmp sgt i32 %x3, 17 469 %s1 = select i1 %c0, i1 %c1, i1 false 470 %s2 = select i1 %s1, i1 %c2, i1 false 471 %s3 = select i1 %s2, i1 %c3, i1 false 472 %s4 = select i1 %s3, i1 %d0, i1 false 473 %s5 = select i1 %s4, i1 %d1, i1 false 474 %s6 = select i1 %s5, i1 %d2, i1 false 475 %s7 = select i1 %s6, i1 %d3, i1 false 476 ret i1 %s7 477} 478 479define i1 @logical_and_icmp_extra_op(<4 x i32> %x, <4 x i32> %y, i1 %c) { 480; CHECK-LABEL: @logical_and_icmp_extra_op( 481; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <4 x i32> [[X:%.*]], [[Y:%.*]] 482; CHECK-NEXT: [[S3:%.*]] = select i1 [[C:%.*]], i1 [[C]], i1 false 483; CHECK-NEXT: [[TMP2:%.*]] = freeze <4 x i1> [[TMP1]] 484; CHECK-NEXT: [[TMP3:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP2]]) 485; CHECK-NEXT: [[OP_RDX:%.*]] = select i1 [[TMP3]], i1 [[S3]], i1 false 486; CHECK-NEXT: ret i1 [[OP_RDX]] 487; 488 %x0 = extractelement <4 x i32> %x, i32 0 489 %x1 = extractelement <4 x i32> %x, i32 1 490 %x2 = extractelement <4 x i32> %x, i32 2 491 %x3 = extractelement <4 x i32> %x, i32 3 492 %y0 = extractelement <4 x i32> %y, i32 0 493 %y1 = extractelement <4 x i32> %y, i32 1 494 %y2 = extractelement <4 x i32> %y, i32 2 495 %y3 = extractelement <4 x i32> %y, i32 3 496 %d0 = icmp slt i32 %x0, %y0 497 %d1 = icmp slt i32 %x1, %y1 498 %d2 = icmp slt i32 %x2, %y2 499 %d3 = icmp slt i32 %x3, %y3 500 %s3 = select i1 %c, i1 %c, i1 false 501 %s4 = select i1 %s3, i1 %d0, i1 false 502 %s5 = select i1 %s4, i1 %d1, i1 false 503 %s6 = select i1 %s5, i1 %d2, i1 false 504 %s7 = select i1 %s6, i1 %d3, i1 false 505 ret i1 %s7 506} 507 508define i1 @logical_or_icmp_extra_op(<4 x i32> %x, <4 x i32> %y, i1 %c) { 509; CHECK-LABEL: @logical_or_icmp_extra_op( 510; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <4 x i32> [[X:%.*]], [[Y:%.*]] 511; CHECK-NEXT: [[S3:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[C]] 512; CHECK-NEXT: [[TMP2:%.*]] = freeze <4 x i1> [[TMP1]] 513; CHECK-NEXT: [[TMP3:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP2]]) 514; CHECK-NEXT: [[OP_RDX:%.*]] = select i1 [[TMP3]], i1 true, i1 [[S3]] 515; CHECK-NEXT: ret i1 [[OP_RDX]] 516; 517 %x0 = extractelement <4 x i32> %x, i32 0 518 %x1 = extractelement <4 x i32> %x, i32 1 519 %x2 = extractelement <4 x i32> %x, i32 2 520 %x3 = extractelement <4 x i32> %x, i32 3 521 %y0 = extractelement <4 x i32> %y, i32 0 522 %y1 = extractelement <4 x i32> %y, i32 1 523 %y2 = extractelement <4 x i32> %y, i32 2 524 %y3 = extractelement <4 x i32> %y, i32 3 525 %d0 = icmp slt i32 %x0, %y0 526 %d1 = icmp slt i32 %x1, %y1 527 %d2 = icmp slt i32 %x2, %y2 528 %d3 = icmp slt i32 %x3, %y3 529 %s3 = select i1 %c, i1 true, i1 %c 530 %s4 = select i1 %s3, i1 true, i1 %d0 531 %s5 = select i1 %s4, i1 true, i1 %d1 532 %s6 = select i1 %s5, i1 true, i1 %d2 533 %s7 = select i1 %s6, i1 true, i1 %d3 534 ret i1 %s7 535} 536