Florian Hahn | 264ab1e | 2020-07-10 09:45:02 +0100 | [diff] [blame] | 1 | ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
Sjoerd Meijer | bda8fbe | 2020-08-26 16:55:25 +0100 | [diff] [blame] | 2 | ; RUN: opt -loop-vectorize -force-vector-width=2 -S -prefer-predicate-over-epilogue=predicate-dont-vectorize %s | FileCheck %s |
Florian Hahn | 264ab1e | 2020-07-10 09:45:02 +0100 | [diff] [blame] | 3 | |
| 4 | |
| 5 | ; Test case for PR46525. There are two candidates to pick for |
| 6 | ; `udiv i64 %y, %add` when expanding SCEV expressions. Make sure we pick %div, |
| 7 | ; which dominates the vector loop. |
| 8 | |
| 9 | define void @test(i16 %x, i64 %y, i32* %ptr) { |
| 10 | ; CHECK-LABEL: @test( |
| 11 | ; CHECK-NEXT: entry: |
| 12 | ; CHECK-NEXT: [[CONV19:%.*]] = sext i16 [[X:%.*]] to i64 |
| 13 | ; CHECK-NEXT: [[ADD:%.*]] = add i64 [[CONV19]], 492802768830814067 |
| 14 | ; CHECK-NEXT: br label [[LOOP_PREHEADER:%.*]] |
| 15 | ; CHECK: loop.preheader: |
| 16 | ; CHECK-NEXT: [[DIV:%.*]] = udiv i64 [[Y:%.*]], [[ADD]] |
| 17 | ; CHECK-NEXT: [[INC:%.*]] = add i64 [[DIV]], 1 |
| 18 | ; CHECK-NEXT: [[TMP0:%.*]] = add nuw nsw i64 [[DIV]], 4 |
| 19 | ; CHECK-NEXT: [[TMP1:%.*]] = udiv i64 [[TMP0]], [[INC]] |
| 20 | ; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i64 [[TMP1]], 1 |
| 21 | ; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] |
| 22 | ; CHECK: vector.ph: |
| 23 | ; CHECK-NEXT: [[N_RND_UP:%.*]] = add i64 [[TMP2]], 1 |
| 24 | ; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[N_RND_UP]], 2 |
| 25 | ; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[N_RND_UP]], [[N_MOD_VF]] |
| 26 | ; CHECK-NEXT: [[IND_END:%.*]] = mul i64 [[N_VEC]], [[INC]] |
| 27 | ; CHECK-NEXT: [[TRIP_COUNT_MINUS_1:%.*]] = sub i64 [[TMP2]], 1 |
| 28 | ; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <2 x i64> undef, i64 [[TRIP_COUNT_MINUS_1]], i32 0 |
| 29 | ; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <2 x i64> [[BROADCAST_SPLATINSERT]], <2 x i64> undef, <2 x i32> zeroinitializer |
| 30 | ; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] |
| 31 | ; CHECK: vector.body: |
| 32 | ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE6:%.*]] ] |
| 33 | ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], [[INC]] |
| 34 | ; CHECK-NEXT: [[BROADCAST_SPLATINSERT1:%.*]] = insertelement <2 x i64> undef, i64 [[OFFSET_IDX]], i32 0 |
| 35 | ; CHECK-NEXT: [[BROADCAST_SPLAT2:%.*]] = shufflevector <2 x i64> [[BROADCAST_SPLATINSERT1]], <2 x i64> undef, <2 x i32> zeroinitializer |
| 36 | ; CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x i64> undef, i64 [[INC]], i32 0 |
| 37 | ; CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <2 x i64> [[DOTSPLATINSERT]], <2 x i64> undef, <2 x i32> zeroinitializer |
| 38 | ; CHECK-NEXT: [[TMP3:%.*]] = mul <2 x i64> <i64 0, i64 1>, [[DOTSPLAT]] |
| 39 | ; CHECK-NEXT: [[INDUCTION:%.*]] = add <2 x i64> [[BROADCAST_SPLAT2]], [[TMP3]] |
| 40 | ; CHECK-NEXT: [[TMP4:%.*]] = mul i64 0, [[INC]] |
| 41 | ; CHECK-NEXT: [[TMP5:%.*]] = add i64 [[OFFSET_IDX]], [[TMP4]] |
| 42 | ; CHECK-NEXT: [[BROADCAST_SPLATINSERT3:%.*]] = insertelement <2 x i64> undef, i64 [[INDEX]], i32 0 |
| 43 | ; CHECK-NEXT: [[BROADCAST_SPLAT4:%.*]] = shufflevector <2 x i64> [[BROADCAST_SPLATINSERT3]], <2 x i64> undef, <2 x i32> zeroinitializer |
| 44 | ; CHECK-NEXT: [[VEC_IV:%.*]] = add <2 x i64> [[BROADCAST_SPLAT4]], <i64 0, i64 1> |
| 45 | ; CHECK-NEXT: [[TMP6:%.*]] = icmp ule <2 x i64> [[VEC_IV]], [[BROADCAST_SPLAT]] |
| 46 | ; CHECK-NEXT: [[TMP7:%.*]] = extractelement <2 x i1> [[TMP6]], i32 0 |
| 47 | ; CHECK-NEXT: br i1 [[TMP7]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]] |
| 48 | ; CHECK: pred.store.if: |
| 49 | ; CHECK-NEXT: store i32 0, i32* [[PTR:%.*]], align 4 |
| 50 | ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE]] |
| 51 | ; CHECK: pred.store.continue: |
| 52 | ; CHECK-NEXT: [[TMP8:%.*]] = extractelement <2 x i1> [[TMP6]], i32 1 |
| 53 | ; CHECK-NEXT: br i1 [[TMP8]], label [[PRED_STORE_IF5:%.*]], label [[PRED_STORE_CONTINUE6]] |
| 54 | ; CHECK: pred.store.if5: |
| 55 | ; CHECK-NEXT: store i32 0, i32* [[PTR]], align 4 |
| 56 | ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE6]] |
| 57 | ; CHECK: pred.store.continue6: |
| 58 | ; CHECK-NEXT: [[OFFSET_IDX7:%.*]] = mul i64 [[INDEX]], [[INC]] |
| 59 | ; CHECK-NEXT: [[TMP9:%.*]] = trunc i64 [[OFFSET_IDX7]] to i8 |
| 60 | ; CHECK-NEXT: [[TMP10:%.*]] = trunc i64 [[INC]] to i8 |
| 61 | ; CHECK-NEXT: [[BROADCAST_SPLATINSERT8:%.*]] = insertelement <2 x i8> undef, i8 [[TMP9]], i32 0 |
| 62 | ; CHECK-NEXT: [[BROADCAST_SPLAT9:%.*]] = shufflevector <2 x i8> [[BROADCAST_SPLATINSERT8]], <2 x i8> undef, <2 x i32> zeroinitializer |
| 63 | ; CHECK-NEXT: [[DOTSPLATINSERT10:%.*]] = insertelement <2 x i8> undef, i8 [[TMP10]], i32 0 |
| 64 | ; CHECK-NEXT: [[DOTSPLAT11:%.*]] = shufflevector <2 x i8> [[DOTSPLATINSERT10]], <2 x i8> undef, <2 x i32> zeroinitializer |
| 65 | ; CHECK-NEXT: [[TMP11:%.*]] = mul <2 x i8> <i8 0, i8 1>, [[DOTSPLAT11]] |
| 66 | ; CHECK-NEXT: [[INDUCTION12:%.*]] = add <2 x i8> [[BROADCAST_SPLAT9]], [[TMP11]] |
| 67 | ; CHECK-NEXT: [[TMP12:%.*]] = mul i8 0, [[TMP10]] |
| 68 | ; CHECK-NEXT: [[TMP13:%.*]] = add i8 [[TMP9]], [[TMP12]] |
| 69 | ; CHECK-NEXT: [[TMP14:%.*]] = add i8 [[TMP13]], 1 |
| 70 | ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 2 |
| 71 | ; CHECK-NEXT: [[TMP15:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] |
David Green | ff86acb | 2020-10-05 13:46:15 +0100 | [diff] [blame] | 72 | ; CHECK-NEXT: br i1 [[TMP15]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], [[LOOP0:!llvm.loop !.*]] |
Florian Hahn | 264ab1e | 2020-07-10 09:45:02 +0100 | [diff] [blame] | 73 | ; |
| 74 | entry: |
| 75 | %conv19 = sext i16 %x to i64 |
| 76 | %add = add i64 %conv19, 492802768830814067 |
| 77 | br label %loop.preheader |
| 78 | |
| 79 | loop.preheader: |
| 80 | %div = udiv i64 %y, %add |
| 81 | %inc = add i64 %div, 1 |
| 82 | br label %loop |
| 83 | |
| 84 | loop: |
| 85 | %iv = phi i64 [ %iv.next, %loop ], [ 0, %loop.preheader ] |
| 86 | store i32 0, i32* %ptr, align 4 |
| 87 | %v2 = trunc i64 %iv to i8 |
| 88 | %v3 = add i8 %v2, 1 |
| 89 | %cmp15 = icmp slt i8 %v3, 5 |
| 90 | %iv.next = add i64 %iv, %inc |
| 91 | br i1 %cmp15, label %loop, label %loop.exit |
| 92 | |
| 93 | loop.exit: |
| 94 | %div.1 = udiv i64 %y, %add |
| 95 | %v1 = add i64 %div.1, 1 |
| 96 | br label %loop.2 |
| 97 | |
| 98 | loop.2: |
| 99 | %iv.1 = phi i64 [ %iv.next.1, %loop.2 ], [ 0, %loop.exit ] |
| 100 | %iv.next.1 = add i64 %iv.1, %v1 |
| 101 | call void @use(i64 %iv.next.1) |
| 102 | %ec = icmp ult i64 %iv.next.1, 200 |
| 103 | br i1 %ec, label %loop.2, label %loop.2.exit |
| 104 | |
| 105 | loop.2.exit: |
| 106 | %c = call i1 @cond() |
| 107 | br i1 %c, label %loop.preheader, label %exit |
| 108 | |
| 109 | exit: |
| 110 | ret void |
| 111 | } |
| 112 | |
| 113 | declare void @use(i64) |
| 114 | declare i1 @cond() |