indirectbr.ll 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. ; RUN: opt -S < %s -jump-threading | FileCheck %s
  2. ; Keep block addresses alive.
  3. @addresses = constant [4 x i8*] [
  4. i8* blockaddress(@test1, %L1), i8* blockaddress(@test1, %L2),
  5. i8* blockaddress(@test2, %L1), i8* blockaddress(@test2, %L2)
  6. ]
  7. declare void @bar()
  8. declare void @baz()
  9. ; Check basic jump threading for indirectbr instructions.
  10. ; CHECK: void @test1
  11. ; CHECK: br i1 %tobool, label %L1, label %indirectgoto
  12. ; CHECK-NOT: if.else:
  13. ; CHECK: L1:
  14. ; CHECK: indirectbr i8* %address, [label %L1, label %L2]
  15. define void @test1(i32 %i, i8* %address) nounwind {
  16. entry:
  17. %rem = srem i32 %i, 2
  18. %tobool = icmp ne i32 %rem, 0
  19. br i1 %tobool, label %indirectgoto, label %if.else
  20. if.else: ; preds = %entry
  21. br label %indirectgoto
  22. L1: ; preds = %indirectgoto
  23. call void @bar()
  24. ret void
  25. L2: ; preds = %indirectgoto
  26. call void @baz()
  27. ret void
  28. indirectgoto: ; preds = %if.else, %entry
  29. %indirect.goto.dest = phi i8* [ %address, %if.else ], [ blockaddress(@test1, %L1), %entry ]
  30. indirectbr i8* %indirect.goto.dest, [label %L1, label %L2]
  31. }
  32. ; Check constant folding of indirectbr
  33. ; CHECK: void @test2
  34. ; CHECK: entry:
  35. ; CHECK-NEXT: br label %L1
  36. ; CHECK: L1:
  37. ; CHECK-NEXT: call void @bar
  38. ; CHECK-NEXT: ret void
  39. define void @test2() nounwind {
  40. entry:
  41. indirectbr i8* blockaddress(@test2, %L1), [label %L1, label %L2]
  42. L1: ; preds = %indirectgoto
  43. call void @bar()
  44. ret void
  45. L2: ; preds = %indirectgoto
  46. call void @baz()
  47. ret void
  48. }
  49. ; PR4151
  50. ; Don't merge address-taken blocks.
  51. @.str = private unnamed_addr constant [4 x i8] c"%p\0A\00"
  52. ; CHECK-LABEL: @test3(
  53. ; CHECK: __here:
  54. ; CHECK: blockaddress(@test3, %__here)
  55. ; CHECK: __here1:
  56. ; CHECK: blockaddress(@test3, %__here1)
  57. ; CHECK: __here3:
  58. ; CHECK: blockaddress(@test3, %__here3)
  59. define void @test3() nounwind ssp noredzone {
  60. entry:
  61. br label %__here
  62. __here: ; preds = %entry
  63. %call = call i32 (...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i64 ptrtoint (i8* blockaddress(@test3, %__here) to i64)) nounwind noredzone
  64. br label %__here1
  65. __here1: ; preds = %__here
  66. %call2 = call i32 (...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i64 ptrtoint (i8* blockaddress(@test3, %__here1) to i64)) nounwind noredzone
  67. br label %__here3
  68. __here3: ; preds = %__here1
  69. %call4 = call i32 (...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i64 ptrtoint (i8* blockaddress(@test3, %__here3) to i64)) nounwind noredzone
  70. ret void
  71. }
  72. declare i32 @printf(...) noredzone