1 ; RUN: opt -p simplifycfg -S %s | FileCheck %s
3 declare void @init(ptr)
5 define i64 @hoist_load_with_matching_pointers_and_tbaa(i1 %c) {
6 ; CHECK-LABEL: define i64 @hoist_load_with_matching_pointers_and_tbaa(
7 ; CHECK-SAME: i1 [[C:%.*]]) {
8 ; CHECK-NEXT: [[ENTRY:.*:]]
9 ; CHECK-NEXT: [[TMP:%.*]] = alloca i64, align 8
10 ; CHECK-NEXT: call void @init(ptr [[TMP]])
11 ; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[TMP]], align 8
13 ; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[TMP]], align 8
15 ; CHECK-NEXT: [[P:%.*]] = select i1 [[C]], i64 [[TMP0]], i64 [[TMP1]]
16 ; CHECK-NEXT: ret i64 [[P]]
19 %tmp = alloca i64, align 8
20 call void @init(ptr %tmp)
21 br i1 %c, label %then, label %else
24 %0 = load i64, ptr %tmp, align 8, !tbaa !0
28 %1 = load i64, ptr %tmp, align 8, !tbaa !0
32 %p = phi i64 [ %0, %then ], [ %1, %else ]
36 define i64 @hoist_load_with_matching_tbaa_different_pointers(i1 %c) {
37 ; CHECK-LABEL: define i64 @hoist_load_with_matching_tbaa_different_pointers(
38 ; CHECK-SAME: i1 [[C:%.*]]) {
39 ; CHECK-NEXT: [[ENTRY:.*:]]
40 ; CHECK-NEXT: [[TMP:%.*]] = alloca i64, align 8
41 ; CHECK-NEXT: [[TMP_1:%.*]] = alloca i64, align 8
42 ; CHECK-NEXT: call void @init(ptr [[TMP]])
43 ; CHECK-NEXT: call void @init(ptr [[TMP_1]])
44 ; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[TMP]], align 8
46 ; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[TMP_1]], align 8
48 ; CHECK-NEXT: [[P:%.*]] = select i1 [[C]], i64 [[TMP0]], i64 [[TMP1]]
49 ; CHECK-NEXT: ret i64 [[P]]
52 %tmp = alloca i64, align 8
53 %tmp.1 = alloca i64, align 8
54 call void @init(ptr %tmp)
55 call void @init(ptr %tmp.1)
56 br i1 %c, label %then, label %else
59 %0 = load i64, ptr %tmp, align 8, !tbaa !0
63 %1 = load i64, ptr %tmp.1, align 8, !tbaa !0
67 %p = phi i64 [ %0, %then ], [ %1, %else ]
71 define i64 @hoist_load_with_different_tbaa(i1 %c) {
72 ; CHECK-LABEL: define i64 @hoist_load_with_different_tbaa(
73 ; CHECK-SAME: i1 [[C:%.*]]) {
74 ; CHECK-NEXT: [[ENTRY:.*:]]
75 ; CHECK-NEXT: [[TMP:%.*]] = alloca i64, align 8
76 ; CHECK-NEXT: call void @init(ptr [[TMP]])
77 ; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[TMP]], align 8
79 ; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[TMP]], align 8
81 ; CHECK-NEXT: [[P:%.*]] = select i1 [[C]], i64 [[TMP0]], i64 [[TMP1]]
82 ; CHECK-NEXT: ret i64 [[P]]
85 %tmp = alloca i64, align 8
86 call void @init(ptr %tmp)
87 br i1 %c, label %then, label %else
90 %0 = load i64, ptr %tmp, align 8, !tbaa !0
94 %1 = load i64, ptr %tmp, align 8, !tbaa !5
98 %p = phi i64 [ %0, %then ], [ %1, %else ]
102 define i64 @hoist_different_ops(i1 %c, i64 %a) {
103 ; CHECK-LABEL: define i64 @hoist_different_ops(
104 ; CHECK-SAME: i1 [[C:%.*]], i64 [[A:%.*]]) {
105 ; CHECK-NEXT: [[ENTRY:.*:]]
106 ; CHECK-NEXT: [[TMP:%.*]] = alloca i64, align 8
107 ; CHECK-NEXT: call void @init(ptr [[TMP]])
108 ; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[TMP]], align 8
110 ; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[A]], 123
111 ; CHECK-NEXT: [[P:%.*]] = select i1 [[C]], i64 [[TMP0]], i64 [[TMP1]]
112 ; CHECK-NEXT: ret i64 [[P]]
115 %tmp = alloca i64, align 8
116 call void @init(ptr %tmp)
117 br i1 %c, label %then, label %else
120 %0 = load i64, ptr %tmp, align 8, !tbaa !0
128 %p = phi i64 [ %0, %then ], [ %1, %else ]
132 !0 = !{!1, !1, i64 0}
133 !1 = !{!"p2 long long", !2, i64 0}
134 !2 = !{!"any pointer", !3, i64 0}
135 !3 = !{!"omnipotent char", !4, i64 0}
136 !4 = !{!"Simple C++ TBAA"}
137 !5 = !{!3, !3, i64 0}