| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 6 |
| ; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s |
| |
| define i64 @early_exit_with_fneg(ptr dereferenceable(1024) align 8 %src, i1 %cond) { |
| ; CHECK-LABEL: define i64 @early_exit_with_fneg( |
| ; CHECK-SAME: ptr align 8 dereferenceable(1024) [[SRC:%.*]], i1 [[COND:%.*]]) { |
| ; CHECK-NEXT: [[LOOP:.*:]] |
| ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] |
| ; CHECK: [[VECTOR_BODY]]: |
| ; CHECK-NEXT: br label %[[VECTOR_BODY1:.*]] |
| ; CHECK: [[VECTOR_BODY1]]: |
| ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[VECTOR_BODY]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY_INTERIM:.*]] ] |
| ; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds double, ptr [[SRC]], i64 [[IV]] |
| ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x double>, ptr [[GEP]], align 8 |
| ; CHECK-NEXT: [[TMP1:%.*]] = fneg <4 x double> [[WIDE_LOAD]] |
| ; CHECK-NEXT: [[TMP2:%.*]] = fcmp oeq <4 x double> [[TMP1]], splat (double 1.000000e+01) |
| ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[IV]], 4 |
| ; CHECK-NEXT: [[TMP3:%.*]] = freeze <4 x i1> [[TMP2]] |
| ; CHECK-NEXT: [[TMP4:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP3]]) |
| ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], 124 |
| ; CHECK-NEXT: br i1 [[TMP4]], label %[[VECTOR_EARLY_EXIT:.*]], label %[[VECTOR_BODY_INTERIM]] |
| ; CHECK: [[VECTOR_BODY_INTERIM]]: |
| ; CHECK-NEXT: br i1 [[TMP5]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY1]], !llvm.loop [[LOOP0:![0-9]+]] |
| ; CHECK: [[MIDDLE_BLOCK]]: |
| ; CHECK-NEXT: br label %[[SCALAR_PH:.*]] |
| ; CHECK: [[VECTOR_EARLY_EXIT]]: |
| ; CHECK-NEXT: [[TMP6:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP2]], i1 false) |
| ; CHECK-NEXT: [[TMP7:%.*]] = add i64 [[IV]], [[TMP6]] |
| ; CHECK-NEXT: br label %[[EARLY_EXIT:.*]] |
| ; CHECK: [[SCALAR_PH]]: |
| ; CHECK-NEXT: br label %[[LOOP_HEADER:.*]] |
| ; CHECK: [[LOOP_HEADER]]: |
| ; CHECK-NEXT: [[IV1:%.*]] = phi i64 [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ], [ 124, %[[SCALAR_PH]] ] |
| ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds double, ptr [[SRC]], i64 [[IV1]] |
| ; CHECK-NEXT: [[VAL:%.*]] = load double, ptr [[GEP1]], align 8 |
| ; CHECK-NEXT: [[NEG:%.*]] = fneg double [[VAL]] |
| ; CHECK-NEXT: [[C_1:%.*]] = fcmp une double [[NEG]], 1.000000e+01 |
| ; CHECK-NEXT: br i1 [[C_1]], label %[[LATCH]], label %[[EARLY_EXIT]] |
| ; CHECK: [[LATCH]]: |
| ; CHECK-NEXT: [[IV_NEXT]] = add nuw i64 [[IV1]], 1 |
| ; CHECK-NEXT: [[EXIT_COND:%.*]] = icmp eq i64 [[IV_NEXT]], 127 |
| ; CHECK-NEXT: br i1 [[EXIT_COND]], label %[[EXIT:.*]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP3:![0-9]+]] |
| ; CHECK: [[EARLY_EXIT]]: |
| ; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[IV1]], %[[LOOP_HEADER]] ], [ [[TMP7]], %[[VECTOR_EARLY_EXIT]] ] |
| ; CHECK-NEXT: ret i64 [[IV_LCSSA]] |
| ; CHECK: [[EXIT]]: |
| ; CHECK-NEXT: ret i64 10 |
| ; |
| entry: |
| br label %loop.header |
| |
| loop.header: |
| %iv = phi i64 [ %iv.next, %latch ], [ 0, %entry ] |
| %gep = getelementptr inbounds double, ptr %src, i64 %iv |
| %val = load double, ptr %gep, align 8 |
| %neg = fneg double %val |
| %c.1 = fcmp une double %neg, 10.0 |
| br i1 %c.1, label %latch, label %early.exit |
| |
| latch: |
| %iv.next = add nuw i64 %iv, 1 |
| %exit.cond = icmp eq i64 %iv.next, 127 |
| br i1 %exit.cond, label %exit, label %loop.header |
| |
| early.exit: |
| ret i64 %iv |
| |
| exit: |
| ret i64 10 |
| } |