| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: opt -p loop-vectorize -S %s | FileCheck %s |
| |
| target triple = "x86_64-unknown-linux-gnu" |
| |
| declare ptr @get() |
| declare i1 @cond() |
| |
| ; Make sure we can clean up the created runtime checks, if vectorization isn't |
| ; profitable. |
| define void @widget(i32 %arg, i64 %arg1, ptr %src) #0 { |
| ; CHECK-LABEL: define void @widget( |
| ; CHECK-SAME: i32 [[ARG:%.*]], i64 [[ARG1:%.*]], ptr [[SRC:%.*]]) #[[ATTR0:[0-9]+]] { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: br label %[[LOOP_1_HEADER:.*]] |
| ; CHECK: [[LOOP_1_HEADER]]: |
| ; CHECK-NEXT: br label %[[INNER_1:.*]] |
| ; CHECK: [[INNER_1]]: |
| ; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() |
| ; CHECK-NEXT: br i1 [[C_1]], label %[[INNER_2:.*]], label %[[INNER_1]] |
| ; CHECK: [[INNER_2]]: |
| ; CHECK-NEXT: [[LOAD:%.*]] = call ptr @get() |
| ; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond() |
| ; CHECK-NEXT: br i1 [[C_2]], label %[[LOOP_2_PREHEADER:.*]], label %[[LOOP_1_LATCH:.*]] |
| ; CHECK: [[LOOP_2_PREHEADER]]: |
| ; CHECK-NEXT: br label %[[LOOP_2:.*]] |
| ; CHECK: [[LOOP_1_LATCH]]: |
| ; CHECK-NEXT: br label %[[LOOP_1_HEADER]] |
| ; CHECK: [[LOOP_2]]: |
| ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP_2]] ], [ [[ARG]], %[[LOOP_2_PREHEADER]] ] |
| ; CHECK-NEXT: [[PHI8:%.*]] = phi i32 [ [[OR:%.*]], %[[LOOP_2]] ], [ 99, %[[LOOP_2_PREHEADER]] ] |
| ; CHECK-NEXT: [[GEP_SRC:%.*]] = getelementptr i32, ptr [[SRC]], i32 [[IV]] |
| ; CHECK-NEXT: [[L:%.*]] = load i32, ptr [[GEP_SRC]], align 4 |
| ; CHECK-NEXT: [[OR]] = or i32 [[PHI8]], [[L]] |
| ; CHECK-NEXT: store i32 [[OR]], ptr [[LOAD]], align 4 |
| ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 |
| ; CHECK-NEXT: [[EC:%.*]] = icmp eq i32 [[IV]], 100 |
| ; CHECK-NEXT: br i1 [[EC]], label %[[EXIT:.*]], label %[[LOOP_2]], !prof [[PROF0:![0-9]+]] |
| ; CHECK: [[EXIT]]: |
| ; CHECK-NEXT: ret void |
| ; |
| entry: |
| br label %loop.1.header |
| |
| loop.1.header: |
| br label %inner.1 |
| |
| inner.1: |
| %c.1 = call i1 @cond() |
| br i1 %c.1, label %inner.2, label %inner.1 |
| |
| inner.2: |
| %load = call ptr @get() |
| %c.2 = call i1 @cond() |
| br i1 %c.2, label %loop.2, label %loop.1.latch |
| |
| loop.1.latch: |
| br label %loop.1.header |
| |
| loop.2: |
| %iv = phi i32 [ %arg, %inner.2 ], [ %iv.next, %loop.2 ] |
| %phi8 = phi i32 [ 99, %inner.2 ], [ %or, %loop.2 ] |
| %gep.src = getelementptr i32, ptr %src, i32 %iv |
| %l = load i32, ptr %gep.src, align 4 |
| %or = or i32 %phi8, %l |
| store i32 %or, ptr %load, align 4 |
| %iv.next = add i32 %iv, 1 |
| %ec = icmp eq i32 %iv, 100 |
| br i1 %ec, label %exit, label %loop.2, !prof !0 |
| |
| exit: |
| ret void |
| } |
| |
| attributes #0 = { "target-features"="+avx2" } |
| !0 = !{!"branch_weights", i32 89478484, i32 1879048192} |
| ;. |
| ; CHECK: [[PROF0]] = !{!"branch_weights", i32 89478484, i32 1879048192} |
| ;. |