1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
; RUN: opt < %s -loop-reduce -S | FileCheck %s
; LSR shouldn't consider %t8 to be an interesting user of %t6, and it
; should be able to form pretty GEPs.
target 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"
; Check that LSR hoists %t2 computation outside the loop,
; folds %t3's add within the address
; and uses the induction variable (%t4) to access the right element.
define void @test(ptr %ptr.i8, ptr %ptr.float) {
; CHECK-LABEL: define void @test
; CHECK-SAME: (ptr [[PTR_I8:%.*]], ptr [[PTR_FLOAT:%.*]]) {
; CHECK-NEXT: bb:
; CHECK-NEXT: br label [[BB3:%.*]]
; CHECK: bb1:
; CHECK-NEXT: br i1 true, label [[BB10:%.*]], label [[BB2:%.*]]
; CHECK: bb2:
; CHECK-NEXT: [[T:%.*]] = add i64 [[T4:%.*]], 1
; CHECK-NEXT: br label [[BB3]]
; CHECK: bb3:
; CHECK-NEXT: [[T4]] = phi i64 [ [[T]], [[BB2]] ], [ 0, [[BB:%.*]] ]
; CHECK-NEXT: br label [[BB1:%.*]]
; CHECK: bb10:
; CHECK-NEXT: [[T7:%.*]] = icmp eq i64 [[T4]], 0
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[PTR_I8]], i64 [[T4]]
; CHECK-NEXT: br label [[BB14:%.*]]
; CHECK: bb14:
; CHECK-NEXT: store i8 undef, ptr [[SCEVGEP]], align 1
; CHECK-NEXT: [[T6:%.*]] = load ptr, ptr [[PTR_FLOAT]], align 8
; CHECK-NEXT: [[SCEVGEP1:%.*]] = getelementptr i8, ptr [[T6]], i64 16
; CHECK-NEXT: [[SCEVGEP2:%.*]] = getelementptr i8, ptr [[SCEVGEP1]], i64 [[T4]]
; CHECK-NEXT: store i8 undef, ptr [[SCEVGEP2]], align 1
; CHECK-NEXT: br label [[BB14]]
;
bb:
br label %bb3
bb1: ; preds = %bb3
br i1 undef, label %bb10, label %bb2
bb2: ; preds = %bb1
%t = add i64 %t4, 1 ; <i64> [#uses=1]
br label %bb3
bb3: ; preds = %bb2, %bb
%t4 = phi i64 [ %t, %bb2 ], [ 0, %bb ] ; <i64> [#uses=3]
br label %bb1
bb10: ; preds = %bb9
%t7 = icmp eq i64 %t4, 0 ; <i1> [#uses=1]
%t3 = add i64 %t4, 16 ; <i64> [#uses=1]
br label %bb14
bb14: ; preds = %bb14, %bb10
%t2 = getelementptr inbounds i8, ptr %ptr.i8, i64 %t4 ; <ptr> [#uses=1]
store i8 undef, ptr %t2
%t6 = load ptr, ptr %ptr.float
%t9 = getelementptr inbounds i8, ptr %t6, i64 %t3 ; <ptr> [#uses=1]
store i8 undef, ptr %t9
br label %bb14
}
; Check that induction variable is initialized to -2.
; IVNEXT covers the uses of %i0 and %t0.
; Therefore, %t0 should be removed and the critical edge must be split.
define fastcc void @TransformLine() nounwind {
; CHECK-LABEL: define fastcc void @TransformLine
; CHECK-SAME: () #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: bb:
; CHECK-NEXT: br label [[LOOP0:%.*]]
; CHECK: loop0:
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], [[LOOP0]] ], [ -2, [[BB:%.*]] ]
; CHECK-NEXT: [[LSR_IV_NEXT]] = add nuw nsw i32 [[LSR_IV]], 1
; CHECK-NEXT: br i1 false, label [[LOOP0]], label [[BB0:%.*]]
; CHECK: bb0:
; CHECK-NEXT: br label [[LOOP1:%.*]]
; CHECK: loop1:
; CHECK-NEXT: [[I1:%.*]] = phi i32 [ 0, [[BB0]] ], [ [[I1_NEXT:%.*]], [[BB5:%.*]] ]
; CHECK-NEXT: br i1 false, label [[BB2:%.*]], label [[LOOP1_BB6_CRIT_EDGE:%.*]]
; CHECK: bb2:
; CHECK-NEXT: br i1 true, label [[BB6SPLITSPLIT:%.*]], label [[BB5]]
; CHECK: bb5:
; CHECK-NEXT: [[I1_NEXT]] = add i32 [[I1]], 1
; CHECK-NEXT: br i1 true, label [[BB5_BB6SPLIT_CRIT_EDGE:%.*]], label [[LOOP1]]
; CHECK: bb5.bb6split_crit_edge:
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LSR_IV_NEXT]], [[I1_NEXT]]
; CHECK-NEXT: br label [[BB6SPLIT:%.*]]
; CHECK: bb6splitsplit:
; CHECK-NEXT: br label [[BB6SPLIT]]
; CHECK: bb6split:
; CHECK-NEXT: [[P8_PH:%.*]] = phi i32 [ [[TMP0]], [[BB5_BB6SPLIT_CRIT_EDGE]] ], [ undef, [[BB6SPLITSPLIT]] ]
; CHECK-NEXT: [[P9_PH:%.*]] = phi i32 [ undef, [[BB5_BB6SPLIT_CRIT_EDGE]] ], [ [[I1]], [[BB6SPLITSPLIT]] ]
; CHECK-NEXT: br label [[BB6:%.*]]
; CHECK: loop1.bb6_crit_edge:
; CHECK-NEXT: [[I1_LCSSA:%.*]] = phi i32 [ [[I1]], [[LOOP1]] ]
; CHECK-NEXT: br label [[BB6]]
; CHECK: bb6:
; CHECK-NEXT: [[P8:%.*]] = phi i32 [ undef, [[LOOP1_BB6_CRIT_EDGE]] ], [ [[P8_PH]], [[BB6SPLIT]] ]
; CHECK-NEXT: [[P9:%.*]] = phi i32 [ [[I1_LCSSA]], [[LOOP1_BB6_CRIT_EDGE]] ], [ [[P9_PH]], [[BB6SPLIT]] ]
; CHECK-NEXT: unreachable
;
bb:
br label %loop0
loop0: ; preds = %loop0, %bb
%i0 = phi i32 [ %i0.next, %loop0 ], [ 0, %bb ] ; <i32> [#uses=2]
%i0.next = add i32 %i0, 1 ; <i32> [#uses=1]
br i1 false, label %loop0, label %bb0
bb0: ; preds = %loop0
br label %loop1
loop1: ; preds = %bb5, %bb0
%i1 = phi i32 [ 0, %bb0 ], [ %i1.next, %bb5 ] ; <i32> [#uses=4]
%t0 = add i32 %i0, %i1 ; <i32> [#uses=1]
br i1 false, label %bb2, label %bb6
bb2: ; preds = %loop1
br i1 true, label %bb6, label %bb5
bb5: ; preds = %bb2
%i1.next = add i32 %i1, 1 ; <i32> [#uses=1]
br i1 true, label %bb6, label %loop1
bb6: ; preds = %bb5, %bb2, %loop1
%p8 = phi i32 [ %t0, %bb5 ], [ undef, %loop1 ], [ undef, %bb2 ] ; <i32> [#uses=0]
%p9 = phi i32 [ undef, %bb5 ], [ %i1, %loop1 ], [ %i1, %bb2 ] ; <i32> [#uses=0]
unreachable
}
|