1; RUN: opt -loop-vectorize -force-vector-width=2 -S %s | FileCheck %s 2 3%s1 = type { [32000 x double], [32000 x double], [32000 x double] } 4 5define i32 @load_with_pointer_phi_no_runtime_checks(%s1* %data) { 6; CHECK-LABEL: @load_with_pointer_phi_no_runtime_checks 7; CHECK-NOT: vector.body 8; 9entry: 10 br label %loop.header 11 12loop.header: ; preds = %loop.latch, %entry 13 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 14 %iv.next = add nuw nsw i64 %iv, 1 15 %cmp5 = icmp ult i64 %iv, 15999 16 %arrayidx = getelementptr inbounds %s1, %s1 * %data, i64 0, i32 0, i64 %iv 17 br i1 %cmp5, label %if.then, label %if.else 18 19if.then: ; preds = %loop.header 20 %gep.1 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 1, i64 %iv 21 br label %loop.latch 22 23if.else: ; preds = %loop.header 24 %gep.2 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 2, i64 %iv 25 br label %loop.latch 26 27loop.latch: ; preds = %if.else, %if.then 28 %gep.2.sink = phi double* [ %gep.2, %if.else ], [ %gep.1, %if.then ] 29 %v8 = load double, double* %gep.2.sink, align 8 30 %mul16 = fmul double 3.0, %v8 31 store double %mul16, double* %arrayidx, align 8 32 %exitcond.not = icmp eq i64 %iv.next, 32000 33 br i1 %exitcond.not, label %exit, label %loop.header 34 35exit: ; preds = %loop.latch 36 ret i32 10 37} 38 39define i32 @store_with_pointer_phi_no_runtime_checks(%s1* %data) { 40; CHECK-LABEL: @store_with_pointer_phi_no_runtime_checks 41; CHECK-NOT: vector.body 42; 43entry: 44 br label %loop.header 45 46loop.header: ; preds = %loop.latch, %entry 47 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 48 %iv.next = add nuw nsw i64 %iv, 1 49 %cmp5 = icmp ult i64 %iv, 15999 50 %arrayidx = getelementptr inbounds %s1, %s1 * %data, i64 0, i32 0, i64 %iv 51 br i1 %cmp5, label %if.then, label %if.else 52 53if.then: ; preds = %loop.header 54 %gep.1 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 1, i64 %iv 55 br label %loop.latch 56 57if.else: ; preds = %loop.header 58 %gep.2 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 2, i64 %iv 59 br label %loop.latch 60 61loop.latch: ; preds = %if.else, %if.then 62 %gep.2.sink = phi double* [ %gep.2, %if.else ], [ %gep.1, %if.then ] 63 %v8 = load double, double* %arrayidx, align 8 64 %mul16 = fmul double 3.0, %v8 65 store double %mul16, double* %gep.2.sink, align 8 66 %exitcond.not = icmp eq i64 %iv.next, 32000 67 br i1 %exitcond.not, label %exit, label %loop.header 68 69exit: ; preds = %loop.latch 70 ret i32 10 71} 72 73define i32 @store_with_pointer_phi_runtime_checks(double* %A, double* %B, double* %C) { 74; CHECK-LABEL: @store_with_pointer_phi_runtime_checks 75; CHECK-NOT: vector.body 76; 77entry: 78 br label %loop.header 79 80loop.header: ; preds = %loop.latch, %entry 81 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 82 %iv.next = add nuw nsw i64 %iv, 1 83 %cmp5 = icmp ult i64 %iv, 15999 84 %arrayidx = getelementptr inbounds double, double* %A, i64 %iv 85 br i1 %cmp5, label %if.then, label %if.else 86 87if.then: ; preds = %loop.header 88 %gep.1 = getelementptr inbounds double, double* %B, i64 %iv 89 br label %loop.latch 90 91if.else: ; preds = %loop.header 92 %gep.2 = getelementptr inbounds double, double* %C, i64 %iv 93 br label %loop.latch 94 95loop.latch: ; preds = %if.else, %if.then 96 %gep.2.sink = phi double* [ %gep.2, %if.else ], [ %gep.1, %if.then ] 97 %v8 = load double, double* %arrayidx, align 8 98 %mul16 = fmul double 3.0, %v8 99 store double %mul16, double* %gep.2.sink, align 8 100 %exitcond.not = icmp eq i64 %iv.next, 32000 101 br i1 %exitcond.not, label %exit, label %loop.header 102 103exit: ; preds = %loop.latch 104 ret i32 10 105} 106 107define i32 @load_with_pointer_phi_outside_loop(double* %A, double* %B, double* %C, i1 %c.0, i1 %c.1) { 108; CHECK-LABEL: @load_with_pointer_phi_outside_loop 109; CHECK-NOT: vector.body 110; 111entry: 112 br i1 %c.0, label %if.then, label %if.else 113 114if.then: 115 br label %loop.ph 116 117if.else: 118 %ptr.select = select i1 %c.1, double* %C, double* %B 119 br label %loop.ph 120 121loop.ph: 122 %ptr = phi double* [ %A, %if.then ], [ %ptr.select, %if.else ] 123 br label %loop.header 124 125loop.header: ; preds = %loop.latch, %entry 126 %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.header ] 127 %iv.next = add nuw nsw i64 %iv, 1 128 %arrayidx = getelementptr inbounds double, double* %A, i64 %iv 129 %v8 = load double, double* %ptr, align 8 130 %mul16 = fmul double 3.0, %v8 131 store double %mul16, double* %arrayidx, align 8 132 %exitcond.not = icmp eq i64 %iv.next, 32000 133 br i1 %exitcond.not, label %exit, label %loop.header 134 135exit: ; preds = %loop.latch 136 ret i32 10 137} 138 139define i32 @store_with_pointer_phi_outside_loop(double* %A, double* %B, double* %C, i1 %c.0, i1 %c.1) { 140; CHECK-LABEL: @store_with_pointer_phi_outside_loop 141; CHECK-NOT: vector.body 142; 143entry: 144 br i1 %c.0, label %if.then, label %if.else 145 146if.then: 147 br label %loop.ph 148 149if.else: 150 %ptr.select = select i1 %c.1, double* %C, double* %B 151 br label %loop.ph 152 153loop.ph: 154 %ptr = phi double* [ %A, %if.then ], [ %ptr.select, %if.else ] 155 br label %loop.header 156 157loop.header: ; preds = %loop.latch, %entry 158 %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.header ] 159 %iv.next = add nuw nsw i64 %iv, 1 160 %arrayidx = getelementptr inbounds double, double* %A, i64 %iv 161 %v8 = load double, double* %arrayidx, align 8 162 %mul16 = fmul double 3.0, %v8 163 store double %mul16, double* %ptr, align 8 164 %exitcond.not = icmp eq i64 %iv.next, 32000 165 br i1 %exitcond.not, label %exit, label %loop.header 166 167exit: ; preds = %loop.latch 168 ret i32 10 169} 170