exit: ; preds = %loop.latch
ret i32 10
}
+
+define i32 @store_with_pointer_phi_incoming_phi(double* %A, double* %B, double* %C, i1 %c.0, i1 %c.1) {
+; CHECK-LABEL: 'store_with_pointer_phi_incoming_phi'
+; CHECK-NEXT: loop.header:
+; CHECK-NEXT: Report: cannot identify array bounds
+; CHECK-NEXT: Dependences:
+; CHECK-NEXT: Run-time memory checks:
+; CHECK-NEXT: Grouped accesses:
+; CHECK-EMPTY
+entry:
+ br label %loop.header
+
+loop.header: ; preds = %loop.latch, %entry
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
+ %iv.next = add nuw nsw i64 %iv, 1
+ %arrayidx = getelementptr inbounds double, double* %A, i64 %iv
+ %v8 = load double, double* %arrayidx, align 8
+ %mul16 = fmul double 3.0, %v8
+ br i1 %c.0, label %loop.then, label %loop.latch
+
+loop.then:
+ br i1 %c.0, label %loop.then.2, label %loop.else.2
+
+loop.then.2:
+ br label %merge.2
+
+loop.else.2:
+ br label %merge.2
+
+
+merge.2:
+ %ptr = phi double* [ %A, %loop.then.2 ], [ %B, %loop.else.2 ]
+ br label %loop.latch
+
+
+loop.latch:
+ %ptr.2 = phi double* [ %ptr, %merge.2], [ %C, %loop.header ]
+ store double %mul16, double* %ptr.2, align 8
+ %exitcond.not = icmp eq i64 %iv.next, 32000
+ br i1 %exitcond.not, label %exit, label %loop.header
+
+exit: ; preds = %loop.latch
+ ret i32 10
+}
+
+; Test cases with pointer phis forming a cycle.
+define i32 @store_with_pointer_phi_incoming_phi_irreducible_cycle(double* %A, double* %B, double* %C, i1 %c.0, i1 %c.1) {
+; CHECK-LABEL: 'store_with_pointer_phi_incoming_phi_irreducible_cycle'
+; CHECK-NEXT: loop.header:
+; CHECK-NEXT: Report: cannot identify array bounds
+; CHECK-NEXT: Dependences:
+; CHECK-NEXT: Run-time memory checks:
+; CHECK-NEXT: Grouped accesses:
+; CHECK-EMPTY
+entry:
+ br label %loop.header
+
+loop.header: ; preds = %loop.latch, %entry
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
+ %iv.next = add nuw nsw i64 %iv, 1
+ %arrayidx = getelementptr inbounds double, double* %A, i64 %iv
+ %v8 = load double, double* %arrayidx, align 8
+ %mul16 = fmul double 3.0, %v8
+ br i1 %c.0, label %loop.then, label %loop.latch
+
+loop.then:
+ br i1 %c.0, label %BB.A, label %BB.B
+
+BB.A:
+ %ptr = phi double* [ %A, %loop.then ], [ %ptr.2, %BB.B ]
+ br label %BB.B
+
+BB.B:
+ %ptr.2 = phi double* [ %ptr, %BB.A ], [ %B, %loop.then ]
+ br i1 %c.1, label %loop.latch, label %BB.A
+
+loop.latch:
+ %ptr.3 = phi double* [ %ptr.2, %BB.B ], [ %C, %loop.header ]
+ store double %mul16, double* %ptr.3, align 8
+ %exitcond.not = icmp eq i64 %iv.next, 32000
+ br i1 %exitcond.not, label %exit, label %loop.header
+
+exit: ; preds = %loop.latch
+ ret i32 10
+}
+
+define i32 @store_with_pointer_phi_outside_loop_select(double* %A, double* %B, double* %C, i1 %c.0, i1 %c.1) {
+; CHECK-LABEL: 'store_with_pointer_phi_outside_loop_select'
+; CHECK-NEXT: loop.header:
+; CHECK-NEXT: Report: unsafe dependent memory operations in loop.
+; CHECK-NEXT: Dependences:
+; CHECK-NEXT: Unknown:
+; CHECK-NEXT: %v8 = load double, double* %arrayidx, align 8 ->
+; CHECK-NEXT: store double %mul16, double* %ptr, align 8
+;
+entry:
+ br i1 %c.0, label %if.then, label %if.else
+
+if.then:
+ br label %loop.ph
+
+if.else:
+ %ptr.select = select i1 %c.1, double* %C, double* %B
+ br label %loop.ph
+
+loop.ph:
+ %ptr = phi double* [ %A, %if.then ], [ %ptr.select, %if.else ]
+ br label %loop.header
+
+loop.header: ; preds = %loop.latch, %entry
+ %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.header ]
+ %iv.next = add nuw nsw i64 %iv, 1
+ %arrayidx = getelementptr inbounds double, double* %A, i64 %iv
+ %v8 = load double, double* %arrayidx, align 8
+ %mul16 = fmul double 3.0, %v8
+ store double %mul16, double* %ptr, align 8
+ %exitcond.not = icmp eq i64 %iv.next, 32000
+ br i1 %exitcond.not, label %exit, label %loop.header
+
+exit: ; preds = %loop.latch
+ ret i32 10
+}
+
+define i32 @store_with_pointer_phi_in_same_bb_use_other_phi(double* %A, double* %B, double* %C, double* %D, i1 %c.0, i1 %c.1) {
+; CHECK-LABEL: Loop access info in function 'store_with_pointer_phi_in_same_bb_use_other_phi':
+; CHECK-NEXT: loop.header:
+; CHECK-NEXT: Report: cannot identify array bounds
+; CHECK-NEXT: Dependences:
+; CHECK-NEXT: Run-time memory checks:
+; CHECK-NEXT: Grouped accesses:
+; CHECK-EMPTY:
+;
+entry:
+ br label %loop.header
+
+loop.header: ; preds = %loop.latch, %entry
+ %ptr.0 = phi double* [ %C, %entry ], [ %D, %loop.header ]
+ %ptr.1 = phi double* [ %B, %entry ], [ %ptr.0, %loop.header ]
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.header ]
+ %iv.next = add nuw nsw i64 %iv, 1
+ %arrayidx = getelementptr inbounds double, double* %A, i64 %iv
+ %v8 = load double, double* %arrayidx, align 8
+ %mul16 = fmul double 3.0, %v8
+ store double %mul16, double* %ptr.1, align 8
+ %exitcond.not = icmp eq i64 %iv.next, 32000
+ br i1 %exitcond.not, label %exit, label %loop.header
+
+exit: ; preds = %loop.latch
+ ret i32 10
+}
+
+define void @phi_load_store_memdep_check(i1 %c, i16* %A, i16* %B, i16* %C) {
+; CHECK-LABEL: Loop access info in function 'phi_load_store_memdep_check':
+; CHECK-NEXT: for.body:
+; CHECK-NEXT: Report: cannot identify array bounds
+; CHECK-NEXT: Dependences:
+; CHECK-NEXT: Run-time memory checks:
+; CHECK-NEXT: Grouped accesses:
+; CHECK-EMPTY:
+;
+entry:
+ br label %for.body
+
+for.body: ; preds = %if.end, %entry
+ %iv = phi i16 [ 0, %entry ], [ %iv.next, %if.end ]
+ %lv = load i16, i16* %A, align 1
+ store i16 %lv, i16* %A, align 1
+ br i1 %c, label %if.then, label %if.end
+
+if.then: ; preds = %for.body
+ %lv2 = load i16, i16* %A, align 1
+ br label %if.end
+
+if.end: ; preds = %if.then, %for.body
+ %c.sink = phi i16* [ %B, %if.then ], [ %C, %for.body ]
+ %lv3 = load i16, i16* %c.sink
+ %add = add i16 %lv3, 10
+ store i16 %add, i16* %c.sink, align 1
+ %iv.next = add nuw nsw i16 %iv, 1
+ %tobool.not = icmp eq i16 %iv.next, 1000
+ br i1 %tobool.not, label %for.end.loopexit, label %for.body
+
+for.end.loopexit: ; preds = %if.end
+ ret void
+}