1; RUN: opt -S -passes=loop-vectorize,dce -force-vector-width=2 -force-vector-interleave=2 < %s | FileCheck %s 2 3target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 4 5@A = common global [1024 x i32] zeroinitializer, align 16 6@fA = common global [1024 x float] zeroinitializer, align 16 7@dA = common global [1024 x double] zeroinitializer, align 16 8 9; Signed tests. 10 11; Turn this into a max reduction. Make sure we use a splat to initialize the 12; vector for the reduction. 13; CHECK-LABEL: @max_red( 14; CHECK: %[[VAR:.*]] = insertelement <2 x i32> poison, i32 %max, i64 0 15; CHECK: {{.*}} = shufflevector <2 x i32> %[[VAR]], <2 x i32> poison, <2 x i32> zeroinitializer 16; CHECK: icmp sgt <2 x i32> 17; CHECK: select <2 x i1> 18; CHECK: middle.block 19; CHECK: call i32 @llvm.vector.reduce.smax.v2i32 20 21define i32 @max_red(i32 %max) { 22entry: 23 br label %for.body 24 25for.body: 26 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 27 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ] 28 %arrayidx = getelementptr inbounds [1024 x i32], ptr @A, i64 0, i64 %indvars.iv 29 %0 = load i32, ptr %arrayidx, align 4 30 %cmp3 = icmp sgt i32 %0, %max.red.08 31 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08 32 %indvars.iv.next = add i64 %indvars.iv, 1 33 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 34 %exitcond = icmp eq i32 %lftr.wideiv, 1024 35 br i1 %exitcond, label %for.end, label %for.body 36 37for.end: 38 ret i32 %max.red.0 39} 40 41; Turn this into a max reduction. The select has its inputs reversed therefore 42; this is a max reduction. 43; CHECK-LABEL: @max_red_inverse_select( 44; CHECK: icmp slt <2 x i32> 45; CHECK: select <2 x i1> 46; CHECK: middle.block 47; CHECK: call i32 @llvm.vector.reduce.smax.v2i32 48 49define i32 @max_red_inverse_select(i32 %max) { 50entry: 51 br label %for.body 52 53for.body: 54 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 55 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ] 56 %arrayidx = getelementptr inbounds [1024 x i32], ptr @A, i64 0, i64 %indvars.iv 57 %0 = load i32, ptr %arrayidx, align 4 58 %cmp3 = icmp slt i32 %max.red.08, %0 59 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08 60 %indvars.iv.next = add i64 %indvars.iv, 1 61 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 62 %exitcond = icmp eq i32 %lftr.wideiv, 1024 63 br i1 %exitcond, label %for.end, label %for.body 64 65for.end: 66 ret i32 %max.red.0 67} 68 69; Turn this into a min reduction. 70; CHECK-LABEL: @min_red( 71; CHECK: icmp slt <2 x i32> 72; CHECK: select <2 x i1> 73; CHECK: middle.block 74; CHECK: call i32 @llvm.vector.reduce.smin.v2i32 75 76define i32 @min_red(i32 %max) { 77entry: 78 br label %for.body 79 80for.body: 81 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 82 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ] 83 %arrayidx = getelementptr inbounds [1024 x i32], ptr @A, i64 0, i64 %indvars.iv 84 %0 = load i32, ptr %arrayidx, align 4 85 %cmp3 = icmp slt i32 %0, %max.red.08 86 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08 87 %indvars.iv.next = add i64 %indvars.iv, 1 88 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 89 %exitcond = icmp eq i32 %lftr.wideiv, 1024 90 br i1 %exitcond, label %for.end, label %for.body 91 92for.end: 93 ret i32 %max.red.0 94} 95 96; Turn this into a min reduction. The select has its inputs reversed therefore 97; this is a min reduction. 98; CHECK-LABEL: @min_red_inverse_select( 99; CHECK: icmp sgt <2 x i32> 100; CHECK: select <2 x i1> 101; CHECK: middle.block 102; CHECK: call i32 @llvm.vector.reduce.smin.v2i32 103 104define i32 @min_red_inverse_select(i32 %max) { 105entry: 106 br label %for.body 107 108for.body: 109 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 110 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ] 111 %arrayidx = getelementptr inbounds [1024 x i32], ptr @A, i64 0, i64 %indvars.iv 112 %0 = load i32, ptr %arrayidx, align 4 113 %cmp3 = icmp sgt i32 %max.red.08, %0 114 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08 115 %indvars.iv.next = add i64 %indvars.iv, 1 116 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 117 %exitcond = icmp eq i32 %lftr.wideiv, 1024 118 br i1 %exitcond, label %for.end, label %for.body 119 120for.end: 121 ret i32 %max.red.0 122} 123 124; Unsigned tests. 125 126; Turn this into a max reduction. 127; CHECK-LABEL: @umax_red( 128; CHECK: icmp ugt <2 x i32> 129; CHECK: select <2 x i1> 130; CHECK: middle.block 131; CHECK: call i32 @llvm.vector.reduce.umax.v2i32 132 133define i32 @umax_red(i32 %max) { 134entry: 135 br label %for.body 136 137for.body: 138 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 139 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ] 140 %arrayidx = getelementptr inbounds [1024 x i32], ptr @A, i64 0, i64 %indvars.iv 141 %0 = load i32, ptr %arrayidx, align 4 142 %cmp3 = icmp ugt i32 %0, %max.red.08 143 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08 144 %indvars.iv.next = add i64 %indvars.iv, 1 145 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 146 %exitcond = icmp eq i32 %lftr.wideiv, 1024 147 br i1 %exitcond, label %for.end, label %for.body 148 149for.end: 150 ret i32 %max.red.0 151} 152 153; Turn this into a max reduction. The select has its inputs reversed therefore 154; this is a max reduction. 155; CHECK-LABEL: @umax_red_inverse_select( 156; CHECK: icmp ult <2 x i32> 157; CHECK: select <2 x i1> 158; CHECK: middle.block 159; CHECK: call i32 @llvm.vector.reduce.umax.v2i32 160 161define i32 @umax_red_inverse_select(i32 %max) { 162entry: 163 br label %for.body 164 165for.body: 166 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 167 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ] 168 %arrayidx = getelementptr inbounds [1024 x i32], ptr @A, i64 0, i64 %indvars.iv 169 %0 = load i32, ptr %arrayidx, align 4 170 %cmp3 = icmp ult i32 %max.red.08, %0 171 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08 172 %indvars.iv.next = add i64 %indvars.iv, 1 173 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 174 %exitcond = icmp eq i32 %lftr.wideiv, 1024 175 br i1 %exitcond, label %for.end, label %for.body 176 177for.end: 178 ret i32 %max.red.0 179} 180 181; Turn this into a min reduction. 182; CHECK-LABEL: @umin_red( 183; CHECK: icmp ult <2 x i32> 184; CHECK: select <2 x i1> 185; CHECK: middle.block 186; CHECK: call i32 @llvm.vector.reduce.umin.v2i32 187 188define i32 @umin_red(i32 %max) { 189entry: 190 br label %for.body 191 192for.body: 193 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 194 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ] 195 %arrayidx = getelementptr inbounds [1024 x i32], ptr @A, i64 0, i64 %indvars.iv 196 %0 = load i32, ptr %arrayidx, align 4 197 %cmp3 = icmp ult i32 %0, %max.red.08 198 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08 199 %indvars.iv.next = add i64 %indvars.iv, 1 200 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 201 %exitcond = icmp eq i32 %lftr.wideiv, 1024 202 br i1 %exitcond, label %for.end, label %for.body 203 204for.end: 205 ret i32 %max.red.0 206} 207 208; Turn this into a min reduction. The select has its inputs reversed therefore 209; this is a min reduction. 210; CHECK-LABEL: @umin_red_inverse_select( 211; CHECK: icmp ugt <2 x i32> 212; CHECK: select <2 x i1> 213; CHECK: middle.block 214; CHECK: call i32 @llvm.vector.reduce.umin.v2i32 215 216define i32 @umin_red_inverse_select(i32 %max) { 217entry: 218 br label %for.body 219 220for.body: 221 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 222 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ] 223 %arrayidx = getelementptr inbounds [1024 x i32], ptr @A, i64 0, i64 %indvars.iv 224 %0 = load i32, ptr %arrayidx, align 4 225 %cmp3 = icmp ugt i32 %max.red.08, %0 226 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08 227 %indvars.iv.next = add i64 %indvars.iv, 1 228 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 229 %exitcond = icmp eq i32 %lftr.wideiv, 1024 230 br i1 %exitcond, label %for.end, label %for.body 231 232for.end: 233 ret i32 %max.red.0 234} 235 236; SGE -> SLT 237; Turn this into a min reduction (select inputs are reversed). 238; CHECK-LABEL: @sge_min_red( 239; CHECK: icmp sge <2 x i32> 240; CHECK: select <2 x i1> 241; CHECK: middle.block 242; CHECK: call i32 @llvm.vector.reduce.smin.v2i32 243 244define i32 @sge_min_red(i32 %max) { 245entry: 246 br label %for.body 247 248for.body: 249 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 250 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ] 251 %arrayidx = getelementptr inbounds [1024 x i32], ptr @A, i64 0, i64 %indvars.iv 252 %0 = load i32, ptr %arrayidx, align 4 253 %cmp3 = icmp sge i32 %0, %max.red.08 254 %max.red.0 = select i1 %cmp3, i32 %max.red.08, i32 %0 255 %indvars.iv.next = add i64 %indvars.iv, 1 256 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 257 %exitcond = icmp eq i32 %lftr.wideiv, 1024 258 br i1 %exitcond, label %for.end, label %for.body 259 260for.end: 261 ret i32 %max.red.0 262} 263 264; SLE -> SGT 265; Turn this into a max reduction (select inputs are reversed). 266; CHECK-LABEL: @sle_min_red( 267; CHECK: icmp sle <2 x i32> 268; CHECK: select <2 x i1> 269; CHECK: middle.block 270; CHECK: call i32 @llvm.vector.reduce.smax.v2i32 271 272define i32 @sle_min_red(i32 %max) { 273entry: 274 br label %for.body 275 276for.body: 277 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 278 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ] 279 %arrayidx = getelementptr inbounds [1024 x i32], ptr @A, i64 0, i64 %indvars.iv 280 %0 = load i32, ptr %arrayidx, align 4 281 %cmp3 = icmp sle i32 %0, %max.red.08 282 %max.red.0 = select i1 %cmp3, i32 %max.red.08, i32 %0 283 %indvars.iv.next = add i64 %indvars.iv, 1 284 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 285 %exitcond = icmp eq i32 %lftr.wideiv, 1024 286 br i1 %exitcond, label %for.end, label %for.body 287 288for.end: 289 ret i32 %max.red.0 290} 291 292; UGE -> ULT 293; Turn this into a min reduction (select inputs are reversed). 294; CHECK-LABEL: @uge_min_red( 295; CHECK: icmp uge <2 x i32> 296; CHECK: select <2 x i1> 297; CHECK: middle.block 298; CHECK: call i32 @llvm.vector.reduce.umin.v2i32 299 300define i32 @uge_min_red(i32 %max) { 301entry: 302 br label %for.body 303 304for.body: 305 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 306 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ] 307 %arrayidx = getelementptr inbounds [1024 x i32], ptr @A, i64 0, i64 %indvars.iv 308 %0 = load i32, ptr %arrayidx, align 4 309 %cmp3 = icmp uge i32 %0, %max.red.08 310 %max.red.0 = select i1 %cmp3, i32 %max.red.08, i32 %0 311 %indvars.iv.next = add i64 %indvars.iv, 1 312 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 313 %exitcond = icmp eq i32 %lftr.wideiv, 1024 314 br i1 %exitcond, label %for.end, label %for.body 315 316for.end: 317 ret i32 %max.red.0 318} 319 320; ULE -> UGT 321; Turn this into a max reduction (select inputs are reversed). 322; CHECK-LABEL: @ule_min_red( 323; CHECK: icmp ule <2 x i32> 324; CHECK: select <2 x i1> 325; CHECK: middle.block 326; CHECK: call i32 @llvm.vector.reduce.umax.v2i32 327 328define i32 @ule_min_red(i32 %max) { 329entry: 330 br label %for.body 331 332for.body: 333 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 334 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ] 335 %arrayidx = getelementptr inbounds [1024 x i32], ptr @A, i64 0, i64 %indvars.iv 336 %0 = load i32, ptr %arrayidx, align 4 337 %cmp3 = icmp ule i32 %0, %max.red.08 338 %max.red.0 = select i1 %cmp3, i32 %max.red.08, i32 %0 339 %indvars.iv.next = add i64 %indvars.iv, 1 340 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 341 %exitcond = icmp eq i32 %lftr.wideiv, 1024 342 br i1 %exitcond, label %for.end, label %for.body 343 344for.end: 345 ret i32 %max.red.0 346} 347 348; No reduction. 349; CHECK-LABEL: @no_red_1( 350; CHECK-NOT: icmp <2 x i32> 351define i32 @no_red_1(i32 %max) { 352entry: 353 br label %for.body 354 355for.body: 356 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 357 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ] 358 %arrayidx = getelementptr inbounds [1024 x i32], ptr @A, i64 0, i64 %indvars.iv 359 %arrayidx1 = getelementptr inbounds [1024 x i32], ptr @A, i64 1, i64 %indvars.iv 360 %0 = load i32, ptr %arrayidx, align 4 361 %1 = load i32, ptr %arrayidx1, align 4 362 %cmp3 = icmp sgt i32 %0, %1 363 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08 364 %indvars.iv.next = add i64 %indvars.iv, 1 365 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 366 %exitcond = icmp eq i32 %lftr.wideiv, 1024 367 br i1 %exitcond, label %for.end, label %for.body 368 369for.end: 370 ret i32 %max.red.0 371} 372 373; CHECK-LABEL: @no_red_2( 374; CHECK-NOT: icmp <2 x i32> 375define i32 @no_red_2(i32 %max) { 376entry: 377 br label %for.body 378 379for.body: 380 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 381 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ] 382 %arrayidx = getelementptr inbounds [1024 x i32], ptr @A, i64 0, i64 %indvars.iv 383 %arrayidx1 = getelementptr inbounds [1024 x i32], ptr @A, i64 1, i64 %indvars.iv 384 %0 = load i32, ptr %arrayidx, align 4 385 %1 = load i32, ptr %arrayidx1, align 4 386 %cmp3 = icmp sgt i32 %0, %max.red.08 387 %max.red.0 = select i1 %cmp3, i32 %0, i32 %1 388 %indvars.iv.next = add i64 %indvars.iv, 1 389 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 390 %exitcond = icmp eq i32 %lftr.wideiv, 1024 391 br i1 %exitcond, label %for.end, label %for.body 392 393for.end: 394 ret i32 %max.red.0 395} 396 397; Float tests. 398 399; Maximum. 400 401; Turn this into a max reduction in the presence of a no-nans-fp-math attribute. 402; CHECK-LABEL: @max_red_float( 403; CHECK: fcmp fast ogt <2 x float> 404; CHECK: select <2 x i1> 405; CHECK: middle.block 406; CHECK: call fast float @llvm.vector.reduce.fmax.v2f32 407 408define float @max_red_float(float %max) #0 { 409entry: 410 br label %for.body 411 412for.body: 413 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 414 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ] 415 %arrayidx = getelementptr inbounds [1024 x float], ptr @fA, i64 0, i64 %indvars.iv 416 %0 = load float, ptr %arrayidx, align 4 417 %cmp3 = fcmp fast ogt float %0, %max.red.08 418 %max.red.0 = select i1 %cmp3, float %0, float %max.red.08 419 %indvars.iv.next = add i64 %indvars.iv, 1 420 %exitcond = icmp eq i64 %indvars.iv.next, 1024 421 br i1 %exitcond, label %for.end, label %for.body 422 423for.end: 424 ret float %max.red.0 425} 426 427; CHECK-LABEL: @max_red_float_ge( 428; CHECK: fcmp fast oge <2 x float> 429; CHECK: select <2 x i1> 430; CHECK: middle.block 431; CHECK: call fast float @llvm.vector.reduce.fmax.v2f32 432 433define float @max_red_float_ge(float %max) #0 { 434entry: 435 br label %for.body 436 437for.body: 438 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 439 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ] 440 %arrayidx = getelementptr inbounds [1024 x float], ptr @fA, i64 0, i64 %indvars.iv 441 %0 = load float, ptr %arrayidx, align 4 442 %cmp3 = fcmp fast oge float %0, %max.red.08 443 %max.red.0 = select i1 %cmp3, float %0, float %max.red.08 444 %indvars.iv.next = add i64 %indvars.iv, 1 445 %exitcond = icmp eq i64 %indvars.iv.next, 1024 446 br i1 %exitcond, label %for.end, label %for.body 447 448for.end: 449 ret float %max.red.0 450} 451 452; CHECK-LABEL: @inverted_max_red_float( 453; CHECK: fcmp fast olt <2 x float> 454; CHECK: select <2 x i1> 455; CHECK: middle.block 456; CHECK: call fast float @llvm.vector.reduce.fmax.v2f32 457 458define float @inverted_max_red_float(float %max) #0 { 459entry: 460 br label %for.body 461 462for.body: 463 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 464 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ] 465 %arrayidx = getelementptr inbounds [1024 x float], ptr @fA, i64 0, i64 %indvars.iv 466 %0 = load float, ptr %arrayidx, align 4 467 %cmp3 = fcmp fast olt float %0, %max.red.08 468 %max.red.0 = select i1 %cmp3, float %max.red.08, float %0 469 %indvars.iv.next = add i64 %indvars.iv, 1 470 %exitcond = icmp eq i64 %indvars.iv.next, 1024 471 br i1 %exitcond, label %for.end, label %for.body 472 473for.end: 474 ret float %max.red.0 475} 476 477; CHECK-LABEL: @inverted_max_red_float_le( 478; CHECK: fcmp fast ole <2 x float> 479; CHECK: select <2 x i1> 480; CHECK: middle.block 481; CHECK: call fast float @llvm.vector.reduce.fmax.v2f32 482 483define float @inverted_max_red_float_le(float %max) #0 { 484entry: 485 br label %for.body 486 487for.body: 488 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 489 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ] 490 %arrayidx = getelementptr inbounds [1024 x float], ptr @fA, i64 0, i64 %indvars.iv 491 %0 = load float, ptr %arrayidx, align 4 492 %cmp3 = fcmp fast ole float %0, %max.red.08 493 %max.red.0 = select i1 %cmp3, float %max.red.08, float %0 494 %indvars.iv.next = add i64 %indvars.iv, 1 495 %exitcond = icmp eq i64 %indvars.iv.next, 1024 496 br i1 %exitcond, label %for.end, label %for.body 497 498for.end: 499 ret float %max.red.0 500} 501 502; CHECK-LABEL: @unordered_max_red_float( 503; CHECK: fcmp fast ugt <2 x float> 504; CHECK: select <2 x i1> 505; CHECK: middle.block 506; CHECK: call fast float @llvm.vector.reduce.fmax.v2f32 507 508define float @unordered_max_red_float(float %max) #0 { 509entry: 510 br label %for.body 511 512for.body: 513 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 514 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ] 515 %arrayidx = getelementptr inbounds [1024 x float], ptr @fA, i64 0, i64 %indvars.iv 516 %0 = load float, ptr %arrayidx, align 4 517 %cmp3 = fcmp fast ugt float %0, %max.red.08 518 %max.red.0 = select i1 %cmp3, float %0, float %max.red.08 519 %indvars.iv.next = add i64 %indvars.iv, 1 520 %exitcond = icmp eq i64 %indvars.iv.next, 1024 521 br i1 %exitcond, label %for.end, label %for.body 522 523for.end: 524 ret float %max.red.0 525} 526 527; CHECK-LABEL: @unordered_max_red_float_ge( 528; CHECK: fcmp fast uge <2 x float> 529; CHECK: select <2 x i1> 530; CHECK: middle.block 531; CHECK: call fast float @llvm.vector.reduce.fmax.v2f32 532 533define float @unordered_max_red_float_ge(float %max) #0 { 534entry: 535 br label %for.body 536 537for.body: 538 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 539 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ] 540 %arrayidx = getelementptr inbounds [1024 x float], ptr @fA, i64 0, i64 %indvars.iv 541 %0 = load float, ptr %arrayidx, align 4 542 %cmp3 = fcmp fast uge float %0, %max.red.08 543 %max.red.0 = select i1 %cmp3, float %0, float %max.red.08 544 %indvars.iv.next = add i64 %indvars.iv, 1 545 %exitcond = icmp eq i64 %indvars.iv.next, 1024 546 br i1 %exitcond, label %for.end, label %for.body 547 548for.end: 549 ret float %max.red.0 550} 551 552; CHECK-LABEL: @inverted_unordered_max_red_float( 553; CHECK: fcmp fast ult <2 x float> 554; CHECK: select <2 x i1> 555; CHECK: middle.block 556; CHECK: call fast float @llvm.vector.reduce.fmax.v2f32 557 558define float @inverted_unordered_max_red_float(float %max) #0 { 559entry: 560 br label %for.body 561 562for.body: 563 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 564 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ] 565 %arrayidx = getelementptr inbounds [1024 x float], ptr @fA, i64 0, i64 %indvars.iv 566 %0 = load float, ptr %arrayidx, align 4 567 %cmp3 = fcmp fast ult float %0, %max.red.08 568 %max.red.0 = select i1 %cmp3, float %max.red.08, float %0 569 %indvars.iv.next = add i64 %indvars.iv, 1 570 %exitcond = icmp eq i64 %indvars.iv.next, 1024 571 br i1 %exitcond, label %for.end, label %for.body 572 573for.end: 574 ret float %max.red.0 575} 576 577; CHECK-LABEL: @inverted_unordered_max_red_float_le( 578; CHECK: fcmp fast ule <2 x float> 579; CHECK: select <2 x i1> 580; CHECK: middle.block 581; CHECK: call fast float @llvm.vector.reduce.fmax.v2f32 582 583define float @inverted_unordered_max_red_float_le(float %max) #0 { 584entry: 585 br label %for.body 586 587for.body: 588 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 589 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ] 590 %arrayidx = getelementptr inbounds [1024 x float], ptr @fA, i64 0, i64 %indvars.iv 591 %0 = load float, ptr %arrayidx, align 4 592 %cmp3 = fcmp fast ule float %0, %max.red.08 593 %max.red.0 = select i1 %cmp3, float %max.red.08, float %0 594 %indvars.iv.next = add i64 %indvars.iv, 1 595 %exitcond = icmp eq i64 %indvars.iv.next, 1024 596 br i1 %exitcond, label %for.end, label %for.body 597 598for.end: 599 ret float %max.red.0 600} 601 602; Minimum. 603 604; Turn this into a min reduction in the presence of a no-nans-fp-math attribute. 605; CHECK-LABEL: @min_red_float( 606; CHECK: fcmp fast olt <2 x float> 607; CHECK: select <2 x i1> 608; CHECK: middle.block 609; CHECK: call fast float @llvm.vector.reduce.fmin.v2f32 610 611define float @min_red_float(float %min) #0 { 612entry: 613 br label %for.body 614 615for.body: 616 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 617 %min.red.08 = phi float [ %min, %entry ], [ %min.red.0, %for.body ] 618 %arrayidx = getelementptr inbounds [1024 x float], ptr @fA, i64 0, i64 %indvars.iv 619 %0 = load float, ptr %arrayidx, align 4 620 %cmp3 = fcmp fast olt float %0, %min.red.08 621 %min.red.0 = select i1 %cmp3, float %0, float %min.red.08 622 %indvars.iv.next = add i64 %indvars.iv, 1 623 %exitcond = icmp eq i64 %indvars.iv.next, 1024 624 br i1 %exitcond, label %for.end, label %for.body 625 626for.end: 627 ret float %min.red.0 628} 629 630; CHECK-LABEL: @min_red_float_le( 631; CHECK: fcmp fast ole <2 x float> 632; CHECK: select <2 x i1> 633; CHECK: middle.block 634; CHECK: call fast float @llvm.vector.reduce.fmin.v2f32 635 636define float @min_red_float_le(float %min) #0 { 637entry: 638 br label %for.body 639 640for.body: 641 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 642 %min.red.08 = phi float [ %min, %entry ], [ %min.red.0, %for.body ] 643 %arrayidx = getelementptr inbounds [1024 x float], ptr @fA, i64 0, i64 %indvars.iv 644 %0 = load float, ptr %arrayidx, align 4 645 %cmp3 = fcmp fast ole float %0, %min.red.08 646 %min.red.0 = select i1 %cmp3, float %0, float %min.red.08 647 %indvars.iv.next = add i64 %indvars.iv, 1 648 %exitcond = icmp eq i64 %indvars.iv.next, 1024 649 br i1 %exitcond, label %for.end, label %for.body 650 651for.end: 652 ret float %min.red.0 653} 654 655; CHECK-LABEL: @inverted_min_red_float( 656; CHECK: fcmp fast ogt <2 x float> 657; CHECK: select <2 x i1> 658; CHECK: middle.block 659; CHECK: call fast float @llvm.vector.reduce.fmin.v2f32 660 661define float @inverted_min_red_float(float %min) #0 { 662entry: 663 br label %for.body 664 665for.body: 666 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 667 %min.red.08 = phi float [ %min, %entry ], [ %min.red.0, %for.body ] 668 %arrayidx = getelementptr inbounds [1024 x float], ptr @fA, i64 0, i64 %indvars.iv 669 %0 = load float, ptr %arrayidx, align 4 670 %cmp3 = fcmp fast ogt float %0, %min.red.08 671 %min.red.0 = select i1 %cmp3, float %min.red.08, float %0 672 %indvars.iv.next = add i64 %indvars.iv, 1 673 %exitcond = icmp eq i64 %indvars.iv.next, 1024 674 br i1 %exitcond, label %for.end, label %for.body 675 676for.end: 677 ret float %min.red.0 678} 679 680; CHECK-LABEL: @inverted_min_red_float_ge( 681; CHECK: fcmp fast oge <2 x float> 682; CHECK: select <2 x i1> 683; CHECK: middle.block 684; CHECK: call fast float @llvm.vector.reduce.fmin.v2f32 685 686define float @inverted_min_red_float_ge(float %min) #0 { 687entry: 688 br label %for.body 689 690for.body: 691 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 692 %min.red.08 = phi float [ %min, %entry ], [ %min.red.0, %for.body ] 693 %arrayidx = getelementptr inbounds [1024 x float], ptr @fA, i64 0, i64 %indvars.iv 694 %0 = load float, ptr %arrayidx, align 4 695 %cmp3 = fcmp fast oge float %0, %min.red.08 696 %min.red.0 = select i1 %cmp3, float %min.red.08, float %0 697 %indvars.iv.next = add i64 %indvars.iv, 1 698 %exitcond = icmp eq i64 %indvars.iv.next, 1024 699 br i1 %exitcond, label %for.end, label %for.body 700 701for.end: 702 ret float %min.red.0 703} 704 705; CHECK-LABEL: @unordered_min_red_float( 706; CHECK: fcmp fast ult <2 x float> 707; CHECK: select <2 x i1> 708; CHECK: middle.block 709; CHECK: call fast float @llvm.vector.reduce.fmin.v2f32 710 711define float @unordered_min_red_float(float %min) #0 { 712entry: 713 br label %for.body 714 715for.body: 716 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 717 %min.red.08 = phi float [ %min, %entry ], [ %min.red.0, %for.body ] 718 %arrayidx = getelementptr inbounds [1024 x float], ptr @fA, i64 0, i64 %indvars.iv 719 %0 = load float, ptr %arrayidx, align 4 720 %cmp3 = fcmp fast ult float %0, %min.red.08 721 %min.red.0 = select i1 %cmp3, float %0, float %min.red.08 722 %indvars.iv.next = add i64 %indvars.iv, 1 723 %exitcond = icmp eq i64 %indvars.iv.next, 1024 724 br i1 %exitcond, label %for.end, label %for.body 725 726for.end: 727 ret float %min.red.0 728} 729 730; CHECK-LABEL: @unordered_min_red_float_le( 731; CHECK: fcmp fast ule <2 x float> 732; CHECK: select <2 x i1> 733; CHECK: middle.block 734; CHECK: call fast float @llvm.vector.reduce.fmin.v2f32 735 736define float @unordered_min_red_float_le(float %min) #0 { 737entry: 738 br label %for.body 739 740for.body: 741 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 742 %min.red.08 = phi float [ %min, %entry ], [ %min.red.0, %for.body ] 743 %arrayidx = getelementptr inbounds [1024 x float], ptr @fA, i64 0, i64 %indvars.iv 744 %0 = load float, ptr %arrayidx, align 4 745 %cmp3 = fcmp fast ule float %0, %min.red.08 746 %min.red.0 = select i1 %cmp3, float %0, float %min.red.08 747 %indvars.iv.next = add i64 %indvars.iv, 1 748 %exitcond = icmp eq i64 %indvars.iv.next, 1024 749 br i1 %exitcond, label %for.end, label %for.body 750 751for.end: 752 ret float %min.red.0 753} 754 755; CHECK-LABEL: @inverted_unordered_min_red_float( 756; CHECK: fcmp fast ugt <2 x float> 757; CHECK: select <2 x i1> 758; CHECK: middle.block 759; CHECK: call fast float @llvm.vector.reduce.fmin.v2f32 760 761define float @inverted_unordered_min_red_float(float %min) #0 { 762entry: 763 br label %for.body 764 765for.body: 766 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 767 %min.red.08 = phi float [ %min, %entry ], [ %min.red.0, %for.body ] 768 %arrayidx = getelementptr inbounds [1024 x float], ptr @fA, i64 0, i64 %indvars.iv 769 %0 = load float, ptr %arrayidx, align 4 770 %cmp3 = fcmp fast ugt float %0, %min.red.08 771 %min.red.0 = select i1 %cmp3, float %min.red.08, float %0 772 %indvars.iv.next = add i64 %indvars.iv, 1 773 %exitcond = icmp eq i64 %indvars.iv.next, 1024 774 br i1 %exitcond, label %for.end, label %for.body 775 776for.end: 777 ret float %min.red.0 778} 779 780; CHECK-LABEL: @inverted_unordered_min_red_float_ge( 781; CHECK: fcmp fast uge <2 x float> 782; CHECK: select <2 x i1> 783; CHECK: middle.block 784; CHECK: call fast float @llvm.vector.reduce.fmin.v2f32 785 786define float @inverted_unordered_min_red_float_ge(float %min) #0 { 787entry: 788 br label %for.body 789 790for.body: 791 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 792 %min.red.08 = phi float [ %min, %entry ], [ %min.red.0, %for.body ] 793 %arrayidx = getelementptr inbounds [1024 x float], ptr @fA, i64 0, i64 %indvars.iv 794 %0 = load float, ptr %arrayidx, align 4 795 %cmp3 = fcmp fast uge float %0, %min.red.08 796 %min.red.0 = select i1 %cmp3, float %min.red.08, float %0 797 %indvars.iv.next = add i64 %indvars.iv, 1 798 %exitcond = icmp eq i64 %indvars.iv.next, 1024 799 br i1 %exitcond, label %for.end, label %for.body 800 801for.end: 802 ret float %min.red.0 803} 804 805; Make sure we handle doubles, too. 806; CHECK-LABEL: @min_red_double( 807; CHECK: fcmp fast olt <2 x double> 808; CHECK: select <2 x i1> 809; CHECK: middle.block 810; CHECK: call fast double @llvm.vector.reduce.fmin.v2f64 811 812define double @min_red_double(double %min) #0 { 813entry: 814 br label %for.body 815 816for.body: 817 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 818 %min.red.08 = phi double [ %min, %entry ], [ %min.red.0, %for.body ] 819 %arrayidx = getelementptr inbounds [1024 x double], ptr @dA, i64 0, i64 %indvars.iv 820 %0 = load double, ptr %arrayidx, align 4 821 %cmp3 = fcmp fast olt double %0, %min.red.08 822 %min.red.0 = select i1 %cmp3, double %0, double %min.red.08 823 %indvars.iv.next = add i64 %indvars.iv, 1 824 %exitcond = icmp eq i64 %indvars.iv.next, 1024 825 br i1 %exitcond, label %for.end, label %for.body 826 827for.end: 828 ret double %min.red.0 829} 830 831 832; Don't this into a max reduction. The no-nans-fp-math attribute is missing 833; CHECK-LABEL: @max_red_float_nans( 834; CHECK-NOT: <2 x float> 835 836define float @max_red_float_nans(float %max) { 837entry: 838 br label %for.body 839 840for.body: 841 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 842 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ] 843 %arrayidx = getelementptr inbounds [1024 x float], ptr @fA, i64 0, i64 %indvars.iv 844 %0 = load float, ptr %arrayidx, align 4 845 %cmp3 = fcmp fast ogt float %0, %max.red.08 846 %max.red.0 = select i1 %cmp3, float %0, float %max.red.08 847 %indvars.iv.next = add i64 %indvars.iv, 1 848 %exitcond = icmp eq i64 %indvars.iv.next, 1024 849 br i1 %exitcond, label %for.end, label %for.body 850 851for.end: 852 ret float %max.red.0 853} 854 855; As above, with the no-signed-zeros-fp-math attribute missing 856; CHECK-LABEL: @max_red_float_nsz( 857; CHECK-NOT: <2 x float> 858 859define float @max_red_float_nsz(float %max) #1 { 860entry: 861 br label %for.body 862 863for.body: 864 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 865 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ] 866 %arrayidx = getelementptr inbounds [1024 x float], ptr @fA, i64 0, i64 %indvars.iv 867 %0 = load float, ptr %arrayidx, align 4 868 %cmp3 = fcmp fast ogt float %0, %max.red.08 869 %max.red.0 = select i1 %cmp3, float %0, float %max.red.08 870 %indvars.iv.next = add i64 %indvars.iv, 1 871 %exitcond = icmp eq i64 %indvars.iv.next, 1024 872 br i1 %exitcond, label %for.end, label %for.body 873 874for.end: 875 ret float %max.red.0 876} 877 878; CHECK-LABEL: @smin_intrinsic( 879; CHECK: <2 x i32> @llvm.smin.v2i32 880; CHECK: i32 @llvm.vector.reduce.smin.v2i32 881define i32 @smin_intrinsic(ptr nocapture readonly %x) { 882entry: 883 br label %for.body 884 885for.body: ; preds = %entry, %for.body 886 %i.012 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 887 %s.011 = phi i32 [ 100, %entry ], [ %1, %for.body ] 888 %arrayidx = getelementptr inbounds i32, ptr %x, i32 %i.012 889 %0 = load i32, ptr %arrayidx, align 4 890 %1 = tail call i32 @llvm.smin.i32(i32 %s.011, i32 %0) 891 %inc = add nuw nsw i32 %i.012, 1 892 %exitcond.not = icmp eq i32 %inc, 1024 893 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 894 895for.cond.cleanup: ; preds = %for.body 896 ret i32 %1 897} 898 899; CHECK-LABEL: @smax_intrinsic( 900; CHECK: <2 x i32> @llvm.smax.v2i32 901; CHECK: i32 @llvm.vector.reduce.smax.v2i32 902define i32 @smax_intrinsic(ptr nocapture readonly %x) { 903entry: 904 br label %for.body 905 906for.body: ; preds = %entry, %for.body 907 %i.012 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 908 %s.011 = phi i32 [ 100, %entry ], [ %1, %for.body ] 909 %arrayidx = getelementptr inbounds i32, ptr %x, i32 %i.012 910 %0 = load i32, ptr %arrayidx, align 4 911 %1 = tail call i32 @llvm.smax.i32(i32 %s.011, i32 %0) 912 %inc = add nuw nsw i32 %i.012, 1 913 %exitcond.not = icmp eq i32 %inc, 1024 914 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 915 916for.cond.cleanup: ; preds = %for.body 917 ret i32 %1 918} 919 920; CHECK-LABEL: @umin_intrinsic( 921; CHECK: <2 x i32> @llvm.umin.v2i32 922; CHECK: i32 @llvm.vector.reduce.umin.v2i32 923define i32 @umin_intrinsic(ptr nocapture readonly %x) { 924entry: 925 br label %for.body 926 927for.body: ; preds = %entry, %for.body 928 %i.012 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 929 %s.011 = phi i32 [ 100, %entry ], [ %1, %for.body ] 930 %arrayidx = getelementptr inbounds i32, ptr %x, i32 %i.012 931 %0 = load i32, ptr %arrayidx, align 4 932 %1 = tail call i32 @llvm.umin.i32(i32 %s.011, i32 %0) 933 %inc = add nuw nsw i32 %i.012, 1 934 %exitcond.not = icmp eq i32 %inc, 1024 935 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 936 937for.cond.cleanup: ; preds = %for.body 938 ret i32 %1 939} 940 941; CHECK-LABEL: @umax_intrinsic( 942; CHECK: <2 x i32> @llvm.umax.v2i32 943; CHECK: i32 @llvm.vector.reduce.umax.v2i32 944define i32 @umax_intrinsic(ptr nocapture readonly %x) { 945entry: 946 br label %for.body 947 948for.body: ; preds = %entry, %for.body 949 %i.012 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 950 %s.011 = phi i32 [ 100, %entry ], [ %1, %for.body ] 951 %arrayidx = getelementptr inbounds i32, ptr %x, i32 %i.012 952 %0 = load i32, ptr %arrayidx, align 4 953 %1 = tail call i32 @llvm.umax.i32(i32 %s.011, i32 %0) 954 %inc = add nuw nsw i32 %i.012, 1 955 %exitcond.not = icmp eq i32 %inc, 1024 956 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 957 958for.cond.cleanup: ; preds = %for.body 959 ret i32 %1 960} 961 962; CHECK-LABEL: @fmin_intrinsic( 963; CHECK: nnan nsz <2 x float> @llvm.minnum.v2f32 964; CHECK: nnan nsz float @llvm.vector.reduce.fmin.v2f32 965define float @fmin_intrinsic(ptr nocapture readonly %x) { 966entry: 967 br label %for.body 968 969for.cond.cleanup: ; preds = %for.body 970 ret float %1 971 972for.body: ; preds = %entry, %for.body 973 %i.012 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 974 %s.011 = phi float [ 0.000000e+00, %entry ], [ %1, %for.body ] 975 %arrayidx = getelementptr inbounds float, ptr %x, i32 %i.012 976 %0 = load float, ptr %arrayidx, align 4 977 %1 = tail call nnan nsz float @llvm.minnum.f32(float %s.011, float %0) 978 %inc = add nuw nsw i32 %i.012, 1 979 %exitcond.not = icmp eq i32 %inc, 1024 980 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 981} 982 983; CHECK-LABEL: @fmax_intrinsic( 984; CHECK: fast <2 x float> @llvm.maxnum.v2f32 985; CHECK: fast float @llvm.vector.reduce.fmax.v2f32 986define float @fmax_intrinsic(ptr nocapture readonly %x) { 987entry: 988 br label %for.body 989 990for.cond.cleanup: ; preds = %for.body 991 ret float %1 992 993for.body: ; preds = %entry, %for.body 994 %i.012 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 995 %s.011 = phi float [ 0.000000e+00, %entry ], [ %1, %for.body ] 996 %arrayidx = getelementptr inbounds float, ptr %x, i32 %i.012 997 %0 = load float, ptr %arrayidx, align 4 998 %1 = tail call fast float @llvm.maxnum.f32(float %s.011, float %0) 999 %inc = add nuw nsw i32 %i.012, 1 1000 %exitcond.not = icmp eq i32 %inc, 1024 1001 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 1002} 1003 1004; CHECK-LABEL: @fmin_intrinsic_nofast( 1005; CHECK-NOT: <2 x float> @llvm.minnum.v2f32 1006define float @fmin_intrinsic_nofast(ptr nocapture readonly %x) { 1007entry: 1008 br label %for.body 1009 1010for.cond.cleanup: ; preds = %for.body 1011 ret float %1 1012 1013for.body: ; preds = %entry, %for.body 1014 %i.012 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 1015 %s.011 = phi float [ 0.000000e+00, %entry ], [ %1, %for.body ] 1016 %arrayidx = getelementptr inbounds float, ptr %x, i32 %i.012 1017 %0 = load float, ptr %arrayidx, align 4 1018 %1 = tail call float @llvm.minnum.f32(float %s.011, float %0) 1019 %inc = add nuw nsw i32 %i.012, 1 1020 %exitcond.not = icmp eq i32 %inc, 1024 1021 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 1022} 1023 1024; CHECK-LABEL: @fmax_intrinsic_nofast( 1025; CHECK-NOT: <2 x float> @llvm.maxnum.v2f32 1026define float @fmax_intrinsic_nofast(ptr nocapture readonly %x) { 1027entry: 1028 br label %for.body 1029 1030for.cond.cleanup: ; preds = %for.body 1031 ret float %1 1032 1033for.body: ; preds = %entry, %for.body 1034 %i.012 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 1035 %s.011 = phi float [ 0.000000e+00, %entry ], [ %1, %for.body ] 1036 %arrayidx = getelementptr inbounds float, ptr %x, i32 %i.012 1037 %0 = load float, ptr %arrayidx, align 4 1038 %1 = tail call float @llvm.maxnum.f32(float %s.011, float %0) 1039 %inc = add nuw nsw i32 %i.012, 1 1040 %exitcond.not = icmp eq i32 %inc, 1024 1041 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 1042} 1043 1044; CHECK-LABEL: @sminmax( 1045; Min and max intrinsics - don't vectorize 1046; CHECK-NOT: <2 x i32> 1047define i32 @sminmax(ptr nocapture readonly %x, ptr nocapture readonly %y) { 1048entry: 1049 br label %for.body 1050 1051for.cond.cleanup: ; preds = %for.body 1052 ret i32 %cond9 1053 1054for.body: ; preds = %entry, %for.body 1055 %i.025 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 1056 %s.024 = phi i32 [ 0, %entry ], [ %cond9, %for.body ] 1057 %arrayidx = getelementptr inbounds i32, ptr %x, i32 %i.025 1058 %0 = load i32, ptr %arrayidx, align 4 1059 %s.0. = tail call i32 @llvm.smin.i32(i32 %s.024, i32 %0) 1060 %arrayidx3 = getelementptr inbounds i32, ptr %y, i32 %i.025 1061 %1 = load i32, ptr %arrayidx3, align 4 1062 %cond9 = tail call i32 @llvm.smax.i32(i32 %s.0., i32 %1) 1063 %inc = add nuw nsw i32 %i.025, 1 1064 %exitcond.not = icmp eq i32 %inc, 1024 1065 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 1066} 1067 1068; CHECK-LABEL: @sminmin( 1069; CHECK: <2 x i32> @llvm.smin.v2i32 1070; CHECK: <2 x i32> @llvm.smin.v2i32 1071; CHECK: i32 @llvm.vector.reduce.smin.v2i32 1072define i32 @sminmin(ptr nocapture readonly %x, ptr nocapture readonly %y) { 1073entry: 1074 br label %for.body 1075 1076for.cond.cleanup: ; preds = %for.body 1077 ret i32 %cond9 1078 1079for.body: ; preds = %entry, %for.body 1080 %i.025 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 1081 %s.024 = phi i32 [ 0, %entry ], [ %cond9, %for.body ] 1082 %arrayidx = getelementptr inbounds i32, ptr %x, i32 %i.025 1083 %0 = load i32, ptr %arrayidx, align 4 1084 %s.0. = tail call i32 @llvm.smin.i32(i32 %s.024, i32 %0) 1085 %arrayidx3 = getelementptr inbounds i32, ptr %y, i32 %i.025 1086 %1 = load i32, ptr %arrayidx3, align 4 1087 %cond9 = tail call i32 @llvm.smin.i32(i32 %s.0., i32 %1) 1088 %inc = add nuw nsw i32 %i.025, 1 1089 %exitcond.not = icmp eq i32 %inc, 1024 1090 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 1091} 1092 1093; CHECK-LABEL: fmaximum_intrinsic 1094; CHECK-LABEL: vector.body: 1095; CHECK: call <2 x float> @llvm.maximum.v2f32 1096; CHECK: call <2 x float> @llvm.maximum.v2f32 1097 1098; CHECK-LABEL: middle.block: 1099; CHECK: call <2 x float> @llvm.maximum.v2f32 1100; CHECK: call float @llvm.vector.reduce.fmaximum.v2f32 1101define float @fmaximum_intrinsic(ptr nocapture readonly %x) { 1102entry: 1103 br label %for.body 1104 1105for.cond.cleanup: ; preds = %for.body 1106 ret float %1 1107 1108for.body: ; preds = %entry, %for.body 1109 %i.012 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 1110 %s.011 = phi float [ 0.000000e+00, %entry ], [ %1, %for.body ] 1111 %arrayidx = getelementptr inbounds float, ptr %x, i32 %i.012 1112 %0 = load float, ptr %arrayidx, align 4 1113 %1 = tail call float @llvm.maximum.f32(float %s.011, float %0) 1114 %inc = add nuw nsw i32 %i.012, 1 1115 %exitcond.not = icmp eq i32 %inc, 1024 1116 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 1117} 1118 1119; CHECK-LABEL: fminimum_intrinsic 1120; CHECK-LABEL: vector.body: 1121; CHECK: call <2 x float> @llvm.minimum.v2f32 1122; CHECK: call <2 x float> @llvm.minimum.v2f32 1123 1124; CHECK-LABEL: middle.block: 1125; CHECK: call <2 x float> @llvm.minimum.v2f32 1126; CHECK: call float @llvm.vector.reduce.fminimum.v2f32 1127define float @fminimum_intrinsic(ptr nocapture readonly %x) { 1128entry: 1129 br label %for.body 1130 1131for.cond.cleanup: ; preds = %for.body 1132 ret float %1 1133 1134for.body: ; preds = %entry, %for.body 1135 %i.012 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 1136 %s.011 = phi float [ 0.000000e+00, %entry ], [ %1, %for.body ] 1137 %arrayidx = getelementptr inbounds float, ptr %x, i32 %i.012 1138 %0 = load float, ptr %arrayidx, align 4 1139 %1 = tail call float @llvm.minimum.f32(float %s.011, float %0) 1140 %inc = add nuw nsw i32 %i.012, 1 1141 %exitcond.not = icmp eq i32 %inc, 1024 1142 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 1143} 1144 1145; CHECK-LABEL: fminimum_fminimum 1146; CHECK-LABEL: vector.body: 1147; CHECK: call <2 x float> @llvm.minimum.v2f32 1148; CHECK: call <2 x float> @llvm.minimum.v2f32 1149; CHECK: call <2 x float> @llvm.minimum.v2f32 1150; CHECK: call <2 x float> @llvm.minimum.v2f32 1151 1152; CHECK-LABEL: middle.block: 1153; CHECK: call <2 x float> @llvm.minimum.v2f32 1154; CHECK: call float @llvm.vector.reduce.fminimum.v2f32 1155define float @fminimum_fminimum(ptr nocapture readonly %x, ptr nocapture readonly %y) { 1156entry: 1157 br label %for.body 1158 1159for.cond.cleanup: ; preds = %for.body 1160 ret float %cond9 1161 1162for.body: ; preds = %entry, %for.body 1163 %i.025 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 1164 %s.011 = phi float [ 0.000000e+00, %entry ], [ %cond9, %for.body ] 1165 %arrayidx = getelementptr inbounds float, ptr %x, i32 %i.025 1166 %0 = load float, ptr %arrayidx, align 4 1167 %s.0. = tail call float @llvm.minimum.f32(float %s.011, float %0) 1168 %arrayidx3 = getelementptr inbounds float, ptr %y, i32 %i.025 1169 %1 = load float, ptr %arrayidx3, align 4 1170 %cond9 = tail call float @llvm.minimum.f32(float %s.0., float %1) 1171 %inc = add nuw nsw i32 %i.025, 1 1172 %exitcond.not = icmp eq i32 %inc, 1024 1173 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 1174} 1175 1176; CHECK-LABEL: fminimum_fminimum_one_with_flags 1177; CHECK-LABEL: vector.body: 1178; CHECK: call nnan nsz <2 x float> @llvm.minimum.v2f32 1179; CHECK: call nnan nsz <2 x float> @llvm.minimum.v2f32 1180; CHECK: call <2 x float> @llvm.minimum.v2f32 1181; CHECK: call <2 x float> @llvm.minimum.v2f32 1182 1183; CHECK-LABEL: middle.block: 1184; CHECK: call <2 x float> @llvm.minimum.v2f32 1185; CHECK: call float @llvm.vector.reduce.fminimum.v2f32 1186define float @fminimum_fminimum_one_with_flags(ptr nocapture readonly %x, ptr nocapture readonly %y) { 1187entry: 1188 br label %for.body 1189 1190for.cond.cleanup: ; preds = %for.body 1191 ret float %cond9 1192 1193for.body: ; preds = %entry, %for.body 1194 %i.025 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 1195 %s.011 = phi float [ 0.000000e+00, %entry ], [ %cond9, %for.body ] 1196 %arrayidx = getelementptr inbounds float, ptr %x, i32 %i.025 1197 %0 = load float, ptr %arrayidx, align 4 1198 %s.0. = tail call nnan nsz float @llvm.minimum.f32(float %s.011, float %0) 1199 %arrayidx3 = getelementptr inbounds float, ptr %y, i32 %i.025 1200 %1 = load float, ptr %arrayidx3, align 4 1201 %cond9 = tail call float @llvm.minimum.f32(float %s.0., float %1) 1202 %inc = add nuw nsw i32 %i.025, 1 1203 %exitcond.not = icmp eq i32 %inc, 1024 1204 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 1205} 1206 1207; Make sure any check-not directives are not triggered by function declarations. 1208; CHECK: declare 1209 1210declare i32 @llvm.smin.i32(i32, i32) 1211declare i32 @llvm.smax.i32(i32, i32) 1212declare i32 @llvm.umin.i32(i32, i32) 1213declare i32 @llvm.umax.i32(i32, i32) 1214declare float @llvm.minnum.f32(float, float) 1215declare float @llvm.maxnum.f32(float, float) 1216declare float @llvm.minimum.f32(float, float) 1217declare float @llvm.maximum.f32(float, float) 1218 1219attributes #0 = { "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" } 1220attributes #1 = { "no-nans-fp-math"="true" } 1221