Home | History | Annotate | Download | only in JumpThreading
      1 ; RUN: opt < %s -jump-threading -S | FileCheck %s
      2 ; Test whether two consecutive switches with identical structures assign the
      3 ; proper value to the proper variable.  This is really testing 
      4 ; Instruction::isIdenticalToWhenDefined, as previously that function was 
      5 ; returning true if the value part of the operands of two phis were identical, 
      6 ; even if the incoming blocks were not.
      7 ; NB: this function should be pruned down more.
      8 
      9 %struct._GList = type { i8*, %struct._GList*, %struct._GList* }
     10 %struct.filter_def = type { i8*, i8* }
     11 
     12 @capture_filters = external hidden global %struct._GList*, align 8
     13 @display_filters = external hidden global %struct._GList*, align 8
     14 @.str2 = external hidden unnamed_addr constant [10 x i8], align 1
     15 @__PRETTY_FUNCTION__.copy_filter_list = external hidden unnamed_addr constant [62 x i8], align 1
     16 @.str12 = external hidden unnamed_addr constant [22 x i8], align 1
     17 @.str13 = external hidden unnamed_addr constant [31 x i8], align 1
     18 @capture_edited_filters = external hidden global %struct._GList*, align 8
     19 @display_edited_filters = external hidden global %struct._GList*, align 8
     20 @__PRETTY_FUNCTION__.get_filter_list = external hidden unnamed_addr constant [44 x i8], align 1
     21 
     22 declare void @g_assertion_message(i8*, i8*, i32, i8*, i8*) noreturn
     23 
     24 declare void @g_free(i8*)
     25 
     26 declare %struct._GList* @g_list_first(%struct._GList*)
     27 
     28 declare noalias i8* @g_malloc(i64)
     29 
     30 define void @copy_filter_list(i32 %dest_type, i32 %src_type) nounwind uwtable ssp {
     31 entry:
     32   br label %do.body
     33 
     34 do.body:                                          ; preds = %entry
     35   %cmp = icmp ne i32 %dest_type, %src_type
     36   br i1 %cmp, label %if.then, label %if.else
     37 
     38 if.then:                                          ; preds = %do.body
     39   br label %if.end
     40 
     41 if.else:                                          ; preds = %do.body
     42   call void @g_assertion_message_expr(i8* null, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str2, i32 0, i32 0), i32 581, i8* getelementptr inbounds ([62 x i8], [62 x i8]* @__PRETTY_FUNCTION__.copy_filter_list, i32 0, i32 0), i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str12, i32 0, i32 0)) noreturn
     43   unreachable
     44 
     45 if.end:                                           ; preds = %if.then
     46   br label %do.end
     47 
     48 do.end:                                           ; preds = %if.end
     49   switch i32 %dest_type, label %sw.default.i [
     50     i32 0, label %sw.bb.i
     51     i32 1, label %sw.bb1.i
     52     i32 2, label %sw.bb2.i
     53     i32 3, label %sw.bb3.i
     54   ]
     55 
     56 sw.bb.i:                                          ; preds = %do.end
     57   br label %get_filter_list.exit
     58 
     59 sw.bb1.i:                                         ; preds = %do.end
     60   br label %get_filter_list.exit
     61 
     62 sw.bb2.i:                                         ; preds = %do.end
     63   br label %get_filter_list.exit
     64 
     65 sw.bb3.i:                                         ; preds = %do.end
     66   br label %get_filter_list.exit
     67 
     68 sw.default.i:                                     ; preds = %do.end
     69   call void @g_assertion_message(i8* null, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str2, i32 0, i32 0), i32 408, i8* getelementptr inbounds ([44 x i8], [44 x i8]* @__PRETTY_FUNCTION__.get_filter_list, i32 0, i32 0), i8* null) noreturn nounwind
     70   unreachable
     71 
     72 get_filter_list.exit:                             ; preds = %sw.bb3.i, %sw.bb2.i, %sw.bb1.i, %sw.bb.i
     73   %0 = phi %struct._GList** [ @display_edited_filters, %sw.bb3.i ], [ @capture_edited_filters, %sw.bb2.i ], [ @display_filters, %sw.bb1.i ], [ @capture_filters, %sw.bb.i ]
     74   switch i32 %src_type, label %sw.default.i5 [
     75     i32 0, label %sw.bb.i1
     76     i32 1, label %sw.bb1.i2
     77     i32 2, label %sw.bb2.i3
     78     i32 3, label %sw.bb3.i4
     79   ]
     80 
     81 sw.bb.i1:                                         ; preds = %get_filter_list.exit
     82   br label %get_filter_list.exit6
     83 
     84 sw.bb1.i2:                                        ; preds = %get_filter_list.exit
     85   br label %get_filter_list.exit6
     86 
     87 sw.bb2.i3:                                        ; preds = %get_filter_list.exit
     88   br label %get_filter_list.exit6
     89 
     90 sw.bb3.i4:                                        ; preds = %get_filter_list.exit
     91   br label %get_filter_list.exit6
     92 
     93 sw.default.i5:                                    ; preds = %get_filter_list.exit
     94   call void @g_assertion_message(i8* null, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str2, i32 0, i32 0), i32 408, i8* getelementptr inbounds ([44 x i8], [44 x i8]* @__PRETTY_FUNCTION__.get_filter_list, i32 0, i32 0), i8* null) noreturn nounwind
     95   unreachable
     96 
     97 ; CHECK: get_filter_list.exit
     98 get_filter_list.exit6:                            ; preds = %sw.bb3.i4, %sw.bb2.i3, %sw.bb1.i2, %sw.bb.i1
     99   %1 = phi %struct._GList** [ @display_edited_filters, %sw.bb3.i4 ], [ @capture_edited_filters, %sw.bb2.i3 ], [ @display_filters, %sw.bb1.i2 ], [ @capture_filters, %sw.bb.i1 ]
    100 ; CHECK: %2 = load
    101   %2 = load %struct._GList*, %struct._GList** %1, align 8
    102 ; We should have jump-threading insert an additional load here for the value
    103 ; coming out of the first switch, which is picked up by a subsequent phi
    104 ; CHECK: %.pr = load %struct._GList*, %struct._GList** %0
    105 ; CHECK-NEXT:  br label %while.cond
    106   br label %while.cond
    107 
    108 ; CHECK: while.cond
    109 while.cond:                                       ; preds = %while.body, %get_filter_list.exit6
    110 ; CHECK: {{= phi .*%.pr}}
    111   %3 = load %struct._GList*, %struct._GList** %0, align 8
    112 ; CHECK: tobool
    113   %tobool = icmp ne %struct._GList* %3, null
    114   br i1 %tobool, label %while.body, label %while.end
    115 
    116 while.body:                                       ; preds = %while.cond
    117   %4 = load %struct._GList*, %struct._GList** %0, align 8
    118   %5 = load %struct._GList*, %struct._GList** %0, align 8
    119   %call2 = call %struct._GList* @g_list_first(%struct._GList* %5)
    120   %data.i = getelementptr inbounds %struct._GList, %struct._GList* %call2, i32 0, i32 0
    121   %6 = load i8*, i8** %data.i, align 8
    122   %7 = bitcast i8* %6 to %struct.filter_def*
    123   %name.i = getelementptr inbounds %struct.filter_def, %struct.filter_def* %7, i32 0, i32 0
    124   %8 = load i8*, i8** %name.i, align 8
    125   call void @g_free(i8* %8) nounwind
    126   %strval.i = getelementptr inbounds %struct.filter_def, %struct.filter_def* %7, i32 0, i32 1
    127   %9 = load i8*, i8** %strval.i, align 8
    128   call void @g_free(i8* %9) nounwind
    129   %10 = bitcast %struct.filter_def* %7 to i8*
    130   call void @g_free(i8* %10) nounwind
    131   %call.i = call %struct._GList* @g_list_remove_link(%struct._GList* %4, %struct._GList* %call2) nounwind
    132   store %struct._GList* %call.i, %struct._GList** %0, align 8
    133   br label %while.cond
    134 
    135 while.end:                                        ; preds = %while.cond
    136   br label %do.body4
    137 
    138 do.body4:                                         ; preds = %while.end
    139   %11 = load %struct._GList*, %struct._GList** %0, align 8
    140   %call5 = call i32 @g_list_length(%struct._GList* %11)
    141   %cmp6 = icmp eq i32 %call5, 0
    142   br i1 %cmp6, label %if.then7, label %if.else8
    143 
    144 if.then7:                                         ; preds = %do.body4
    145   br label %if.end9
    146 
    147 if.else8:                                         ; preds = %do.body4
    148   call void @g_assertion_message_expr(i8* null, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str2, i32 0, i32 0), i32 600, i8* getelementptr inbounds ([62 x i8], [62 x i8]* @__PRETTY_FUNCTION__.copy_filter_list, i32 0, i32 0), i8* getelementptr inbounds ([31 x i8], [31 x i8]* @.str13, i32 0, i32 0)) noreturn
    149   unreachable
    150 
    151 if.end9:                                          ; preds = %if.then7
    152   br label %do.end10
    153 
    154 do.end10:                                         ; preds = %if.end9
    155   br label %while.cond11
    156 
    157 while.cond11:                                     ; preds = %cond.end, %do.end10
    158   %cond10 = phi %struct._GList* [ %cond, %cond.end ], [ %2, %do.end10 ]
    159   %tobool12 = icmp ne %struct._GList* %cond10, null
    160   br i1 %tobool12, label %while.body13, label %while.end16
    161 
    162 while.body13:                                     ; preds = %while.cond11
    163   %data = getelementptr inbounds %struct._GList, %struct._GList* %cond10, i32 0, i32 0
    164   %12 = load i8*, i8** %data, align 8
    165   %13 = bitcast i8* %12 to %struct.filter_def*
    166   %14 = load %struct._GList*, %struct._GList** %0, align 8
    167   %name = getelementptr inbounds %struct.filter_def, %struct.filter_def* %13, i32 0, i32 0
    168   %15 = load i8*, i8** %name, align 8
    169   %strval = getelementptr inbounds %struct.filter_def, %struct.filter_def* %13, i32 0, i32 1
    170   %16 = load i8*, i8** %strval, align 8
    171   %call.i7 = call noalias i8* @g_malloc(i64 16) nounwind
    172   %17 = bitcast i8* %call.i7 to %struct.filter_def*
    173   %call1.i = call noalias i8* @g_strdup(i8* %15) nounwind
    174   %name.i8 = getelementptr inbounds %struct.filter_def, %struct.filter_def* %17, i32 0, i32 0
    175   store i8* %call1.i, i8** %name.i8, align 8
    176   %call2.i = call noalias i8* @g_strdup(i8* %16) nounwind
    177   %strval.i9 = getelementptr inbounds %struct.filter_def, %struct.filter_def* %17, i32 0, i32 1
    178   store i8* %call2.i, i8** %strval.i9, align 8
    179   %18 = bitcast %struct.filter_def* %17 to i8*
    180   %call3.i = call %struct._GList* @g_list_append(%struct._GList* %14, i8* %18) nounwind
    181   store %struct._GList* %call3.i, %struct._GList** %0, align 8
    182   %tobool15 = icmp ne %struct._GList* %cond10, null
    183   br i1 %tobool15, label %cond.true, label %cond.false
    184 
    185 cond.true:                                        ; preds = %while.body13
    186   %next = getelementptr inbounds %struct._GList, %struct._GList* %cond10, i32 0, i32 1
    187   %19 = load %struct._GList*, %struct._GList** %next, align 8
    188   br label %cond.end
    189 
    190 cond.false:                                       ; preds = %while.body13
    191   br label %cond.end
    192 
    193 cond.end:                                         ; preds = %cond.false, %cond.true
    194   %cond = phi %struct._GList* [ %19, %cond.true ], [ null, %cond.false ]
    195   br label %while.cond11
    196 
    197 while.end16:                                      ; preds = %while.cond11
    198   ret void
    199 }
    200 
    201 declare void @g_assertion_message_expr(i8*, i8*, i32, i8*, i8*) noreturn
    202 
    203 declare i32 @g_list_length(%struct._GList*)
    204 
    205 declare noalias i8* @g_strdup(i8*)
    206 
    207 declare %struct._GList* @g_list_append(%struct._GList*, i8*)
    208 
    209 declare %struct._GList* @g_list_remove_link(%struct._GList*, %struct._GList*)
    210