1; RUN: opt -loop-accesses -analyze -enable-new-pm=0 < %s | FileCheck %s 2; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck %s 3 4%s1 = type { [32000 x double], [32000 x double], [32000 x double] } 5 6define i32 @load_with_pointer_phi_no_runtime_checks(%s1* %data) { 7; CHECK-LABEL: load_with_pointer_phi_no_runtime_checks 8; CHECK-NEXT: loop.header: 9; CHECK-NEXT: Memory dependences are safe 10; 11entry: 12 br label %loop.header 13 14loop.header: ; preds = %loop.latch, %entry 15 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 16 %iv.next = add nuw nsw i64 %iv, 1 17 %cmp5 = icmp ult i64 %iv, 15999 18 %arrayidx = getelementptr inbounds %s1, %s1 * %data, i64 0, i32 0, i64 %iv 19 br i1 %cmp5, label %if.then, label %if.else 20 21if.then: ; preds = %loop.header 22 %gep.1 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 1, i64 %iv 23 br label %loop.latch 24 25if.else: ; preds = %loop.header 26 %gep.2 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 2, i64 %iv 27 br label %loop.latch 28 29loop.latch: ; preds = %if.else, %if.then 30 %gep.2.sink = phi double* [ %gep.2, %if.else ], [ %gep.1, %if.then ] 31 %v8 = load double, double* %gep.2.sink, align 8 32 %mul16 = fmul double 3.0, %v8 33 store double %mul16, double* %arrayidx, align 8 34 %exitcond.not = icmp eq i64 %iv.next, 32000 35 br i1 %exitcond.not, label %exit, label %loop.header 36 37exit: ; preds = %loop.latch 38 ret i32 10 39} 40 41define i32 @store_with_pointer_phi_no_runtime_checks(%s1* %data) { 42; CHECK-LABEL: 'store_with_pointer_phi_no_runtime_checks' 43; CHECK-NEXT: loop.header: 44; CHECK-NEXT: Memory dependences are safe 45; 46entry: 47 br label %loop.header 48 49loop.header: ; preds = %loop.latch, %entry 50 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 51 %iv.next = add nuw nsw i64 %iv, 1 52 %cmp5 = icmp ult i64 %iv, 15999 53 %arrayidx = getelementptr inbounds %s1, %s1 * %data, i64 0, i32 0, i64 %iv 54 br i1 %cmp5, label %if.then, label %if.else 55 56if.then: ; preds = %loop.header 57 %gep.1 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 1, i64 %iv 58 br label %loop.latch 59 60if.else: ; preds = %loop.header 61 %gep.2 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 2, i64 %iv 62 br label %loop.latch 63 64loop.latch: ; preds = %if.else, %if.then 65 %gep.2.sink = phi double* [ %gep.2, %if.else ], [ %gep.1, %if.then ] 66 %v8 = load double, double* %arrayidx, align 8 67 %mul16 = fmul double 3.0, %v8 68 store double %mul16, double* %gep.2.sink, align 8 69 %exitcond.not = icmp eq i64 %iv.next, 32000 70 br i1 %exitcond.not, label %exit, label %loop.header 71 72exit: ; preds = %loop.latch 73 ret i32 10 74} 75 76define i32 @store_with_pointer_phi_runtime_checks(double* %A, double* %B, double* %C) { 77; CHECK-LABEL: 'store_with_pointer_phi_runtime_checks' 78; CHECK-NEXT: loop.header: 79; CHECK-NEXT: Memory dependences are safe with run-time checks 80; CHECK: Run-time memory checks: 81; CHECK-NEXT: Check 0: 82; CHECK-NEXT: Comparing group ([[GROUP_C:.+]]): 83; CHECK-NEXT: %gep.2 = getelementptr inbounds double, double* %C, i64 %iv 84; CHECK-NEXT: Against group ([[GROUP_B:.+]]): 85; CHECK-NEXT: %gep.1 = getelementptr inbounds double, double* %B, i64 %iv 86; CHECK-NEXT: Check 1: 87; CHECK-NEXT: Comparing group ([[GROUP_C]]): 88; CHECK-NEXT: %gep.2 = getelementptr inbounds double, double* %C, i64 %iv 89; CHECK-NEXT: Against group ([[GROUP_A:.+]]): 90; CHECK-NEXT: %arrayidx = getelementptr inbounds double, double* %A, i64 %iv 91; CHECK-NEXT: Check 2: 92; CHECK-NEXT: Comparing group ([[GROUP_B]]): 93; CHECK-NEXT: %gep.1 = getelementptr inbounds double, double* %B, i64 %iv 94; CHECK-NEXT: Against group ([[GROUP_A]]): 95; CHECK-NEXT: %arrayidx = getelementptr inbounds double, double* %A, i64 %iv 96; 97entry: 98 br label %loop.header 99 100loop.header: ; preds = %loop.latch, %entry 101 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 102 %iv.next = add nuw nsw i64 %iv, 1 103 %cmp5 = icmp ult i64 %iv, 15999 104 %arrayidx = getelementptr inbounds double, double* %A, i64 %iv 105 br i1 %cmp5, label %if.then, label %if.else 106 107if.then: ; preds = %loop.header 108 %gep.1 = getelementptr inbounds double, double* %B, i64 %iv 109 br label %loop.latch 110 111if.else: ; preds = %loop.header 112 %gep.2 = getelementptr inbounds double, double* %C, i64 %iv 113 br label %loop.latch 114 115loop.latch: ; preds = %if.else, %if.then 116 %gep.2.sink = phi double* [ %gep.2, %if.else ], [ %gep.1, %if.then ] 117 %v8 = load double, double* %arrayidx, align 8 118 %mul16 = fmul double 3.0, %v8 119 store double %mul16, double* %gep.2.sink, align 8 120 %exitcond.not = icmp eq i64 %iv.next, 32000 121 br i1 %exitcond.not, label %exit, label %loop.header 122 123exit: ; preds = %loop.latch 124 ret i32 10 125} 126 127define i32 @load_with_pointer_phi_outside_loop(double* %A, double* %B, double* %C, i1 %c.0, i1 %c.1) { 128; CHECK-LABEL: 'load_with_pointer_phi_outside_loop' 129; CHECK-NEXT: loop.header: 130; CHECK-NEXT: Report: unsafe dependent memory operations in loop 131; CHECK-NEXT: Dependences: 132; CHECK-NEXT: Unknown: 133; CHECK-NEXT: %v8 = load double, double* %ptr, align 8 -> 134; CHECK-NEXT: store double %mul16, double* %arrayidx, align 8 135; 136entry: 137 br i1 %c.0, label %if.then, label %if.else 138 139if.then: 140 br label %loop.ph 141 142if.else: 143 %ptr.select = select i1 %c.1, double* %C, double* %B 144 br label %loop.ph 145 146loop.ph: 147 %ptr = phi double* [ %A, %if.then ], [ %ptr.select, %if.else ] 148 br label %loop.header 149 150loop.header: ; preds = %loop.latch, %entry 151 %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.header ] 152 %iv.next = add nuw nsw i64 %iv, 1 153 %arrayidx = getelementptr inbounds double, double* %A, i64 %iv 154 %v8 = load double, double* %ptr, align 8 155 %mul16 = fmul double 3.0, %v8 156 store double %mul16, double* %arrayidx, align 8 157 %exitcond.not = icmp eq i64 %iv.next, 32000 158 br i1 %exitcond.not, label %exit, label %loop.header 159 160exit: ; preds = %loop.latch 161 ret i32 10 162} 163 164define i32 @store_with_pointer_phi_outside_loop(double* %A, double* %B, double* %C, i1 %c.0, i1 %c.1) { 165; CHECK-LABEL: 'store_with_pointer_phi_outside_loop' 166; CHECK-NEXT: loop.header: 167; CHECK-NEXT: Report: unsafe dependent memory operations in loop. 168; CHECK-NEXT: Dependences: 169; CHECK-NEXT: Unknown: 170; CHECK-NEXT: %v8 = load double, double* %arrayidx, align 8 -> 171; CHECK-NEXT: store double %mul16, double* %ptr, align 8 172; 173entry: 174 br i1 %c.0, label %if.then, label %if.else 175 176if.then: 177 br label %loop.ph 178 179if.else: 180 %ptr.select = select i1 %c.1, double* %C, double* %B 181 br label %loop.ph 182 183loop.ph: 184 %ptr = phi double* [ %A, %if.then ], [ %ptr.select, %if.else ] 185 br label %loop.header 186 187loop.header: ; preds = %loop.latch, %entry 188 %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.header ] 189 %iv.next = add nuw nsw i64 %iv, 1 190 %arrayidx = getelementptr inbounds double, double* %A, i64 %iv 191 %v8 = load double, double* %arrayidx, align 8 192 %mul16 = fmul double 3.0, %v8 193 store double %mul16, double* %ptr, align 8 194 %exitcond.not = icmp eq i64 %iv.next, 32000 195 br i1 %exitcond.not, label %exit, label %loop.header 196 197exit: ; preds = %loop.latch 198 ret i32 10 199} 200