phi-eq.ll 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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. %struct._GList = type { i8*, %struct._GList*, %struct._GList* }
  9. %struct.filter_def = type { i8*, i8* }
  10. @capture_filters = external hidden global %struct._GList*, align 8
  11. @display_filters = external hidden global %struct._GList*, align 8
  12. @.str2 = external hidden unnamed_addr constant [10 x i8], align 1
  13. @__PRETTY_FUNCTION__.copy_filter_list = external hidden unnamed_addr constant [62 x i8], align 1
  14. @.str12 = external hidden unnamed_addr constant [22 x i8], align 1
  15. @.str13 = external hidden unnamed_addr constant [31 x i8], align 1
  16. @capture_edited_filters = external hidden global %struct._GList*, align 8
  17. @display_edited_filters = external hidden global %struct._GList*, align 8
  18. @__PRETTY_FUNCTION__.get_filter_list = external hidden unnamed_addr constant [44 x i8], align 1
  19. declare void @g_assertion_message(i8*, i8*, i32, i8*, i8*) noreturn
  20. declare void @g_free(i8*)
  21. declare %struct._GList* @g_list_first(%struct._GList*)
  22. declare noalias i8* @g_malloc(i64)
  23. define void @copy_filter_list(i32 %dest_type, i32 %src_type) nounwind uwtable ssp {
  24. entry:
  25. br label %do.body
  26. do.body: ; preds = %entry
  27. %cmp = icmp ne i32 %dest_type, %src_type
  28. br i1 %cmp, label %if.then, label %if.else
  29. if.then: ; preds = %do.body
  30. br label %if.end
  31. if.else: ; preds = %do.body
  32. 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
  33. unreachable
  34. if.end: ; preds = %if.then
  35. br label %do.end
  36. do.end: ; preds = %if.end
  37. switch i32 %dest_type, label %sw.default.i [
  38. i32 0, label %sw.bb.i
  39. i32 1, label %sw.bb1.i
  40. i32 2, label %sw.bb2.i
  41. i32 3, label %sw.bb3.i
  42. ]
  43. sw.bb.i: ; preds = %do.end
  44. br label %get_filter_list.exit
  45. sw.bb1.i: ; preds = %do.end
  46. br label %get_filter_list.exit
  47. sw.bb2.i: ; preds = %do.end
  48. br label %get_filter_list.exit
  49. sw.bb3.i: ; preds = %do.end
  50. br label %get_filter_list.exit
  51. sw.default.i: ; preds = %do.end
  52. 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
  53. unreachable
  54. get_filter_list.exit: ; preds = %sw.bb3.i, %sw.bb2.i, %sw.bb1.i, %sw.bb.i
  55. %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 ]
  56. switch i32 %src_type, label %sw.default.i5 [
  57. i32 0, label %sw.bb.i1
  58. i32 1, label %sw.bb1.i2
  59. i32 2, label %sw.bb2.i3
  60. i32 3, label %sw.bb3.i4
  61. ]
  62. sw.bb.i1: ; preds = %get_filter_list.exit
  63. br label %get_filter_list.exit6
  64. sw.bb1.i2: ; preds = %get_filter_list.exit
  65. br label %get_filter_list.exit6
  66. sw.bb2.i3: ; preds = %get_filter_list.exit
  67. br label %get_filter_list.exit6
  68. sw.bb3.i4: ; preds = %get_filter_list.exit
  69. br label %get_filter_list.exit6
  70. sw.default.i5: ; preds = %get_filter_list.exit
  71. 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
  72. unreachable
  73. ; CHECK: get_filter_list.exit
  74. get_filter_list.exit6: ; preds = %sw.bb3.i4, %sw.bb2.i3, %sw.bb1.i2, %sw.bb.i1
  75. %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 ]
  76. ; CHECK: %2 = load
  77. %2 = load %struct._GList*, %struct._GList** %1, align 8
  78. ; We should have jump-threading insert an additional load here for the value
  79. ; coming out of the first switch, which is picked up by a subsequent phi
  80. ; CHECK: %.pr = load %struct._GList*, %struct._GList** %0
  81. ; CHECK-NEXT: br label %while.cond
  82. br label %while.cond
  83. ; CHECK: while.cond
  84. while.cond: ; preds = %while.body, %get_filter_list.exit6
  85. ; CHECK: {{= phi .*%.pr}}
  86. %3 = load %struct._GList*, %struct._GList** %0, align 8
  87. ; CHECK: tobool
  88. %tobool = icmp ne %struct._GList* %3, null
  89. br i1 %tobool, label %while.body, label %while.end
  90. while.body: ; preds = %while.cond
  91. %4 = load %struct._GList*, %struct._GList** %0, align 8
  92. %5 = load %struct._GList*, %struct._GList** %0, align 8
  93. %call2 = call %struct._GList* @g_list_first(%struct._GList* %5)
  94. %data.i = getelementptr inbounds %struct._GList, %struct._GList* %call2, i32 0, i32 0
  95. %6 = load i8*, i8** %data.i, align 8
  96. %7 = bitcast i8* %6 to %struct.filter_def*
  97. %name.i = getelementptr inbounds %struct.filter_def, %struct.filter_def* %7, i32 0, i32 0
  98. %8 = load i8*, i8** %name.i, align 8
  99. call void @g_free(i8* %8) nounwind
  100. %strval.i = getelementptr inbounds %struct.filter_def, %struct.filter_def* %7, i32 0, i32 1
  101. %9 = load i8*, i8** %strval.i, align 8
  102. call void @g_free(i8* %9) nounwind
  103. %10 = bitcast %struct.filter_def* %7 to i8*
  104. call void @g_free(i8* %10) nounwind
  105. %call.i = call %struct._GList* @g_list_remove_link(%struct._GList* %4, %struct._GList* %call2) nounwind
  106. store %struct._GList* %call.i, %struct._GList** %0, align 8
  107. br label %while.cond
  108. while.end: ; preds = %while.cond
  109. br label %do.body4
  110. do.body4: ; preds = %while.end
  111. %11 = load %struct._GList*, %struct._GList** %0, align 8
  112. %call5 = call i32 @g_list_length(%struct._GList* %11)
  113. %cmp6 = icmp eq i32 %call5, 0
  114. br i1 %cmp6, label %if.then7, label %if.else8
  115. if.then7: ; preds = %do.body4
  116. br label %if.end9
  117. if.else8: ; preds = %do.body4
  118. 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
  119. unreachable
  120. if.end9: ; preds = %if.then7
  121. br label %do.end10
  122. do.end10: ; preds = %if.end9
  123. br label %while.cond11
  124. while.cond11: ; preds = %cond.end, %do.end10
  125. %cond10 = phi %struct._GList* [ %cond, %cond.end ], [ %2, %do.end10 ]
  126. %tobool12 = icmp ne %struct._GList* %cond10, null
  127. br i1 %tobool12, label %while.body13, label %while.end16
  128. while.body13: ; preds = %while.cond11
  129. %data = getelementptr inbounds %struct._GList, %struct._GList* %cond10, i32 0, i32 0
  130. %12 = load i8*, i8** %data, align 8
  131. %13 = bitcast i8* %12 to %struct.filter_def*
  132. %14 = load %struct._GList*, %struct._GList** %0, align 8
  133. %name = getelementptr inbounds %struct.filter_def, %struct.filter_def* %13, i32 0, i32 0
  134. %15 = load i8*, i8** %name, align 8
  135. %strval = getelementptr inbounds %struct.filter_def, %struct.filter_def* %13, i32 0, i32 1
  136. %16 = load i8*, i8** %strval, align 8
  137. %call.i7 = call noalias i8* @g_malloc(i64 16) nounwind
  138. %17 = bitcast i8* %call.i7 to %struct.filter_def*
  139. %call1.i = call noalias i8* @g_strdup(i8* %15) nounwind
  140. %name.i8 = getelementptr inbounds %struct.filter_def, %struct.filter_def* %17, i32 0, i32 0
  141. store i8* %call1.i, i8** %name.i8, align 8
  142. %call2.i = call noalias i8* @g_strdup(i8* %16) nounwind
  143. %strval.i9 = getelementptr inbounds %struct.filter_def, %struct.filter_def* %17, i32 0, i32 1
  144. store i8* %call2.i, i8** %strval.i9, align 8
  145. %18 = bitcast %struct.filter_def* %17 to i8*
  146. %call3.i = call %struct._GList* @g_list_append(%struct._GList* %14, i8* %18) nounwind
  147. store %struct._GList* %call3.i, %struct._GList** %0, align 8
  148. %tobool15 = icmp ne %struct._GList* %cond10, null
  149. br i1 %tobool15, label %cond.true, label %cond.false
  150. cond.true: ; preds = %while.body13
  151. %next = getelementptr inbounds %struct._GList, %struct._GList* %cond10, i32 0, i32 1
  152. %19 = load %struct._GList*, %struct._GList** %next, align 8
  153. br label %cond.end
  154. cond.false: ; preds = %while.body13
  155. br label %cond.end
  156. cond.end: ; preds = %cond.false, %cond.true
  157. %cond = phi %struct._GList* [ %19, %cond.true ], [ null, %cond.false ]
  158. br label %while.cond11
  159. while.end16: ; preds = %while.cond11
  160. ret void
  161. }
  162. declare void @g_assertion_message_expr(i8*, i8*, i32, i8*, i8*) noreturn
  163. declare i32 @g_list_length(%struct._GList*)
  164. declare noalias i8* @g_strdup(i8*)
  165. declare %struct._GList* @g_list_append(%struct._GList*, i8*)
  166. declare %struct._GList* @g_list_remove_link(%struct._GList*, %struct._GList*)