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 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
|
; RUN: opt < %s -passes=jump-threading -S | FileCheck %s
; Test whether two consecutive switches with identical structures assign the
; proper value to the proper variable. This is really testing
; Instruction::isIdenticalToWhenDefined, as previously that function was
; returning true if the value part of the operands of two phis were identical,
; even if the incoming blocks were not.
; NB: this function should be pruned down more.
%struct._GList = type { ptr, ptr, ptr }
%struct.filter_def = type { ptr, ptr }
@capture_filters = external hidden global ptr, align 8
@display_filters = external hidden global ptr, align 8
@.str2 = external hidden unnamed_addr constant [10 x i8], align 1
@__PRETTY_FUNCTION__.copy_filter_list = external hidden unnamed_addr constant [62 x i8], align 1
@.str12 = external hidden unnamed_addr constant [22 x i8], align 1
@.str13 = external hidden unnamed_addr constant [31 x i8], align 1
@capture_edited_filters = external hidden global ptr, align 8
@display_edited_filters = external hidden global ptr, align 8
@__PRETTY_FUNCTION__.get_filter_list = external hidden unnamed_addr constant [44 x i8], align 1
declare void @g_assertion_message(ptr, ptr, i32, ptr, ptr) noreturn
declare void @g_free(ptr)
declare ptr @g_list_first(ptr)
declare noalias ptr @g_malloc(i64)
define void @copy_filter_list(i32 %dest_type, i32 %src_type) nounwind uwtable ssp {
entry:
br label %do.body
do.body: ; preds = %entry
%cmp = icmp ne i32 %dest_type, %src_type
br i1 %cmp, label %if.then, label %if.else
if.then: ; preds = %do.body
br label %if.end
if.else: ; preds = %do.body
call void @g_assertion_message_expr(ptr null, ptr @.str2, i32 581, ptr @__PRETTY_FUNCTION__.copy_filter_list, ptr @.str12) noreturn
unreachable
if.end: ; preds = %if.then
br label %do.end
do.end: ; preds = %if.end
switch i32 %dest_type, label %sw.default.i [
i32 0, label %sw.bb.i
i32 1, label %sw.bb1.i
i32 2, label %sw.bb2.i
i32 3, label %sw.bb3.i
]
sw.bb.i: ; preds = %do.end
br label %get_filter_list.exit
sw.bb1.i: ; preds = %do.end
br label %get_filter_list.exit
sw.bb2.i: ; preds = %do.end
br label %get_filter_list.exit
sw.bb3.i: ; preds = %do.end
br label %get_filter_list.exit
sw.default.i: ; preds = %do.end
call void @g_assertion_message(ptr null, ptr @.str2, i32 408, ptr @__PRETTY_FUNCTION__.get_filter_list, ptr null) noreturn nounwind
unreachable
get_filter_list.exit: ; preds = %sw.bb3.i, %sw.bb2.i, %sw.bb1.i, %sw.bb.i
%0 = phi ptr [ @display_edited_filters, %sw.bb3.i ], [ @capture_edited_filters, %sw.bb2.i ], [ @display_filters, %sw.bb1.i ], [ @capture_filters, %sw.bb.i ]
switch i32 %src_type, label %sw.default.i5 [
i32 0, label %sw.bb.i1
i32 1, label %sw.bb1.i2
i32 2, label %sw.bb2.i3
i32 3, label %sw.bb3.i4
]
sw.bb.i1: ; preds = %get_filter_list.exit
br label %get_filter_list.exit6
sw.bb1.i2: ; preds = %get_filter_list.exit
br label %get_filter_list.exit6
sw.bb2.i3: ; preds = %get_filter_list.exit
br label %get_filter_list.exit6
sw.bb3.i4: ; preds = %get_filter_list.exit
br label %get_filter_list.exit6
sw.default.i5: ; preds = %get_filter_list.exit
call void @g_assertion_message(ptr null, ptr @.str2, i32 408, ptr @__PRETTY_FUNCTION__.get_filter_list, ptr null) noreturn nounwind
unreachable
; CHECK: get_filter_list.exit
get_filter_list.exit6: ; preds = %sw.bb3.i4, %sw.bb2.i3, %sw.bb1.i2, %sw.bb.i1
%1 = phi ptr [ @display_edited_filters, %sw.bb3.i4 ], [ @capture_edited_filters, %sw.bb2.i3 ], [ @display_filters, %sw.bb1.i2 ], [ @capture_filters, %sw.bb.i1 ]
; CHECK: %2 = load
%2 = load ptr, ptr %1, align 8
; We should have jump-threading insert an additional load here for the value
; coming out of the first switch, which is picked up by a subsequent phi
; CHECK: %.pr = load ptr, ptr %0
; CHECK-NEXT: br label %while.cond
br label %while.cond
; CHECK: while.cond
while.cond: ; preds = %while.body, %get_filter_list.exit6
; CHECK: {{= phi .*%.pr}}
%3 = load ptr, ptr %0, align 8
; CHECK: tobool
%tobool = icmp ne ptr %3, null
br i1 %tobool, label %while.body, label %while.end
while.body: ; preds = %while.cond
%4 = load ptr, ptr %0, align 8
%5 = load ptr, ptr %0, align 8
%call2 = call ptr @g_list_first(ptr %5)
%6 = load ptr, ptr %call2, align 8
%7 = load ptr, ptr %6, align 8
call void @g_free(ptr %7) nounwind
%strval.i = getelementptr inbounds %struct.filter_def, ptr %6, i32 0, i32 1
%8 = load ptr, ptr %strval.i, align 8
call void @g_free(ptr %8) nounwind
call void @g_free(ptr %6) nounwind
%call.i = call ptr @g_list_remove_link(ptr %4, ptr %call2) nounwind
store ptr %call.i, ptr %0, align 8
br label %while.cond
while.end: ; preds = %while.cond
br label %do.body4
do.body4: ; preds = %while.end
%9 = load ptr, ptr %0, align 8
%call5 = call i32 @g_list_length(ptr %9)
%cmp6 = icmp eq i32 %call5, 0
br i1 %cmp6, label %if.then7, label %if.else8
if.then7: ; preds = %do.body4
br label %if.end9
if.else8: ; preds = %do.body4
call void @g_assertion_message_expr(ptr null, ptr @.str2, i32 600, ptr @__PRETTY_FUNCTION__.copy_filter_list, ptr @.str13) noreturn
unreachable
if.end9: ; preds = %if.then7
br label %do.end10
do.end10: ; preds = %if.end9
br label %while.cond11
while.cond11: ; preds = %cond.end, %do.end10
%cond10 = phi ptr [ %cond, %cond.end ], [ %2, %do.end10 ]
%tobool12 = icmp ne ptr %cond10, null
br i1 %tobool12, label %while.body13, label %while.end16
while.body13: ; preds = %while.cond11
%10 = load ptr, ptr %cond10, align 8
%11 = load ptr, ptr %0, align 8
%12 = load ptr, ptr %10, align 8
%strval = getelementptr inbounds %struct.filter_def, ptr %10, i32 0, i32 1
%13 = load ptr, ptr %strval, align 8
%call.i7 = call noalias ptr @g_malloc(i64 16) nounwind
%call1.i = call noalias ptr @g_strdup(ptr %12) nounwind
store ptr %call1.i, ptr %call.i7, align 8
%call2.i = call noalias ptr @g_strdup(ptr %13) nounwind
%strval.i9 = getelementptr inbounds %struct.filter_def, ptr %call.i7, i32 0, i32 1
store ptr %call2.i, ptr %strval.i9, align 8
%call3.i = call ptr @g_list_append(ptr %11, ptr %call.i7) nounwind
store ptr %call3.i, ptr %0, align 8
%tobool15 = icmp ne ptr %cond10, null
br i1 %tobool15, label %cond.true, label %cond.false
cond.true: ; preds = %while.body13
%next = getelementptr inbounds %struct._GList, ptr %cond10, i32 0, i32 1
%14 = load ptr, ptr %next, align 8
br label %cond.end
cond.false: ; preds = %while.body13
br label %cond.end
cond.end: ; preds = %cond.false, %cond.true
%cond = phi ptr [ %14, %cond.true ], [ null, %cond.false ]
br label %while.cond11
while.end16: ; preds = %while.cond11
ret void
}
declare void @g_assertion_message_expr(ptr, ptr, i32, ptr, ptr) noreturn
declare i32 @g_list_length(ptr)
declare noalias ptr @g_strdup(ptr)
declare ptr @g_list_append(ptr, ptr)
declare ptr @g_list_remove_link(ptr, ptr)
|