aggregates.ll 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. ; RUN: opt -S -deadargelim %s | FileCheck %s
  2. ; Case 0: the basic example: an entire aggregate use is returned, but it's
  3. ; actually only used in ways we can eliminate. We gain benefit from analysing
  4. ; the "use" and applying its results to all sub-values.
  5. ; CHECK-LABEL: define internal void @agguse_dead()
  6. define internal { i32, i32 } @agguse_dead() {
  7. ret { i32, i32 } { i32 0, i32 1 }
  8. }
  9. define internal { i32, i32 } @test_agguse_dead() {
  10. %val = call { i32, i32 } @agguse_dead()
  11. ret { i32, i32 } %val
  12. }
  13. ; Case 1: an opaque use of the aggregate exists (in this case dead). Otherwise
  14. ; only one value is used, so function can be simplified.
  15. ; CHECK-LABEL: define internal i32 @rets_independent_if_agguse_dead()
  16. ; CHECK: [[RET:%.*]] = extractvalue { i32, i32 } { i32 0, i32 1 }, 1
  17. ; CHECK: ret i32 [[RET]]
  18. define internal { i32, i32 } @rets_independent_if_agguse_dead() {
  19. ret { i32, i32 } { i32 0, i32 1 }
  20. }
  21. define internal { i32, i32 } @test_rets_independent_if_agguse_dead(i1 %tst) {
  22. %val = call { i32, i32 } @rets_independent_if_agguse_dead()
  23. br i1 %tst, label %use_1, label %use_aggregate
  24. use_1:
  25. ; This use can be classified as applying only to ret 1.
  26. %val0 = extractvalue { i32, i32 } %val, 1
  27. call void @callee(i32 %val0)
  28. ret { i32, i32 } undef
  29. use_aggregate:
  30. ; This use is assumed to apply to both 0 and 1.
  31. ret { i32, i32 } %val
  32. }
  33. ; Case 2: an opaque use of the aggregate exists (in this case *live*). Other
  34. ; uses shouldn't matter.
  35. ; CHECK-LABEL: define internal { i32, i32 } @rets_live_agguse()
  36. ; CHECK: ret { i32, i32 } { i32 0, i32 1 }
  37. define internal { i32, i32 } @rets_live_agguse() {
  38. ret { i32, i32} { i32 0, i32 1 }
  39. }
  40. define { i32, i32 } @test_rets_live_aggues(i1 %tst) {
  41. %val = call { i32, i32 } @rets_live_agguse()
  42. br i1 %tst, label %use_1, label %use_aggregate
  43. use_1:
  44. ; This use can be classified as applying only to ret 1.
  45. %val0 = extractvalue { i32, i32 } %val, 1
  46. call void @callee(i32 %val0)
  47. ret { i32, i32 } undef
  48. use_aggregate:
  49. ; This use is assumed to apply to both 0 and 1.
  50. ret { i32, i32 } %val
  51. }
  52. declare void @callee(i32)
  53. ; Case 3: the insertvalue meant %in was live if ret-slot-1 was, but we were only
  54. ; tracking multiple ret-slots for struct types. So %in was eliminated
  55. ; incorrectly.
  56. ; CHECK-LABEL: define internal [2 x i32] @array_rets_have_multiple_slots(i32 %in)
  57. define internal [2 x i32] @array_rets_have_multiple_slots(i32 %in) {
  58. %ret = insertvalue [2 x i32] undef, i32 %in, 1
  59. ret [2 x i32] %ret
  60. }
  61. define [2 x i32] @test_array_rets_have_multiple_slots() {
  62. %res = call [2 x i32] @array_rets_have_multiple_slots(i32 42)
  63. ret [2 x i32] %res
  64. }
  65. ; Case 4: we can remove some retvals from the array. It's nice to produce an
  66. ; array again having done so (rather than converting it to a struct).
  67. ; CHECK-LABEL: define internal [2 x i32] @can_shrink_arrays()
  68. ; CHECK: [[VAL0:%.*]] = extractvalue [3 x i32] [i32 42, i32 43, i32 44], 0
  69. ; CHECK: [[RESTMP:%.*]] = insertvalue [2 x i32] undef, i32 [[VAL0]], 0
  70. ; CHECK: [[VAL2:%.*]] = extractvalue [3 x i32] [i32 42, i32 43, i32 44], 2
  71. ; CHECK: [[RES:%.*]] = insertvalue [2 x i32] [[RESTMP]], i32 [[VAL2]], 1
  72. ; CHECK: ret [2 x i32] [[RES]]
  73. ; CHECK-LABEL: define void @test_can_shrink_arrays()
  74. define internal [3 x i32] @can_shrink_arrays() {
  75. ret [3 x i32] [i32 42, i32 43, i32 44]
  76. }
  77. define void @test_can_shrink_arrays() {
  78. %res = call [3 x i32] @can_shrink_arrays()
  79. %res.0 = extractvalue [3 x i32] %res, 0
  80. call void @callee(i32 %res.0)
  81. %res.2 = extractvalue [3 x i32] %res, 2
  82. call void @callee(i32 %res.2)
  83. ret void
  84. }
  85. ; Case 5: %in gets passed directly to the return. It should mark be marked as
  86. ; used if *any* of the return values are, not just if value 0 is.
  87. ; CHECK-LABEL: define internal i32 @ret_applies_to_all({ i32, i32 } %in)
  88. ; CHECK: [[RET:%.*]] = extractvalue { i32, i32 } %in, 1
  89. ; CHECK: ret i32 [[RET]]
  90. define internal {i32, i32} @ret_applies_to_all({i32, i32} %in) {
  91. ret {i32, i32} %in
  92. }
  93. define i32 @test_ret_applies_to_all() {
  94. %val = call {i32, i32} @ret_applies_to_all({i32, i32} {i32 42, i32 43})
  95. %ret = extractvalue {i32, i32} %val, 1
  96. ret i32 %ret
  97. }
  98. ; Case 6: When considering @mid, the return instruciton has sub-value 0
  99. ; unconditionally live, but 1 only conditionally live. Since at that level we're
  100. ; applying the results to the whole of %res, this means %res is live and cannot
  101. ; be reduced. There is scope for further optimisation here (though not visible
  102. ; in this test-case).
  103. ; CHECK-LABEL: define internal { i8*, i32 } @inner()
  104. define internal {i8*, i32} @mid() {
  105. %res = call {i8*, i32} @inner()
  106. %intval = extractvalue {i8*, i32} %res, 1
  107. %tst = icmp eq i32 %intval, 42
  108. br i1 %tst, label %true, label %true
  109. true:
  110. ret {i8*, i32} %res
  111. }
  112. define internal {i8*, i32} @inner() {
  113. ret {i8*, i32} {i8* null, i32 42}
  114. }
  115. define internal i8 @outer() {
  116. %res = call {i8*, i32} @mid()
  117. %resptr = extractvalue {i8*, i32} %res, 0
  118. %val = load i8, i8* %resptr
  119. ret i8 %val
  120. }