volatile.ll 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. ; Tests that check our handling of volatile instructions encountered
  2. ; when scanning for dependencies
  3. ; RUN: opt -basicaa -gvn -S < %s | FileCheck %s
  4. ; Check that we can bypass a volatile load when searching
  5. ; for dependencies of a non-volatile load
  6. define i32 @test1(i32* nocapture %p, i32* nocapture %q) {
  7. ; CHECK-LABEL: test1
  8. ; CHECK: %0 = load volatile i32, i32* %q
  9. ; CHECK-NEXT: ret i32 0
  10. entry:
  11. %x = load i32, i32* %p
  12. load volatile i32, i32* %q
  13. %y = load i32, i32* %p
  14. %add = sub i32 %y, %x
  15. ret i32 %add
  16. }
  17. ; We can not value forward if the query instruction is
  18. ; volatile, this would be (in effect) removing the volatile load
  19. define i32 @test2(i32* nocapture %p, i32* nocapture %q) {
  20. ; CHECK-LABEL: test2
  21. ; CHECK: %x = load i32, i32* %p
  22. ; CHECK-NEXT: %y = load volatile i32, i32* %p
  23. ; CHECK-NEXT: %add = sub i32 %y, %x
  24. entry:
  25. %x = load i32, i32* %p
  26. %y = load volatile i32, i32* %p
  27. %add = sub i32 %y, %x
  28. ret i32 %add
  29. }
  30. ; If the query instruction is itself volatile, we *cannot*
  31. ; reorder it even if p and q are noalias
  32. define i32 @test3(i32* noalias nocapture %p, i32* noalias nocapture %q) {
  33. ; CHECK-LABEL: test3
  34. ; CHECK: %x = load i32, i32* %p
  35. ; CHECK-NEXT: %0 = load volatile i32, i32* %q
  36. ; CHECK-NEXT: %y = load volatile i32, i32* %p
  37. entry:
  38. %x = load i32, i32* %p
  39. load volatile i32, i32* %q
  40. %y = load volatile i32, i32* %p
  41. %add = sub i32 %y, %x
  42. ret i32 %add
  43. }
  44. ; If an encountered instruction is both volatile and ordered,
  45. ; we need to use the strictest ordering of either. In this
  46. ; case, the ordering prevents forwarding.
  47. define i32 @test4(i32* noalias nocapture %p, i32* noalias nocapture %q) {
  48. ; CHECK-LABEL: test4
  49. ; CHECK: %x = load i32, i32* %p
  50. ; CHECK-NEXT: %0 = load atomic volatile i32, i32* %q seq_cst
  51. ; CHECK-NEXT: %y = load atomic i32, i32* %p seq_cst
  52. entry:
  53. %x = load i32, i32* %p
  54. load atomic volatile i32, i32* %q seq_cst, align 4
  55. %y = load atomic i32, i32* %p seq_cst, align 4
  56. %add = sub i32 %y, %x
  57. ret i32 %add
  58. }
  59. ; Value forwarding from a volatile load is perfectly legal
  60. define i32 @test5(i32* nocapture %p, i32* nocapture %q) {
  61. ; CHECK-LABEL: test5
  62. ; CHECK: %x = load volatile i32, i32* %p
  63. ; CHECK-NEXT: ret i32 0
  64. entry:
  65. %x = load volatile i32, i32* %p
  66. %y = load i32, i32* %p
  67. %add = sub i32 %y, %x
  68. ret i32 %add
  69. }
  70. ; Does cross block redundancy elimination work with volatiles?
  71. define i32 @test6(i32* noalias nocapture %p, i32* noalias nocapture %q) {
  72. ; CHECK-LABEL: test6
  73. ; CHECK: %y1 = load i32, i32* %p
  74. ; CHECK-LABEL: header
  75. ; CHECK: %x = load volatile i32, i32* %q
  76. ; CHECK-NEXT: %add = sub i32 %y1, %x
  77. entry:
  78. %y1 = load i32, i32* %p
  79. call void @use(i32 %y1)
  80. br label %header
  81. header:
  82. %x = load volatile i32, i32* %q
  83. %y = load i32, i32* %p
  84. %add = sub i32 %y, %x
  85. %cnd = icmp eq i32 %add, 0
  86. br i1 %cnd, label %exit, label %header
  87. exit:
  88. ret i32 %add
  89. }
  90. ; Does cross block PRE work with volatiles?
  91. define i32 @test7(i1 %c, i32* noalias nocapture %p, i32* noalias nocapture %q) {
  92. ; CHECK-LABEL: test7
  93. ; CHECK-LABEL: entry.header_crit_edge:
  94. ; CHECK: %y.pre = load i32, i32* %p
  95. ; CHECK-LABEL: skip:
  96. ; CHECK: %y1 = load i32, i32* %p
  97. ; CHECK-LABEL: header:
  98. ; CHECK: %y = phi i32
  99. ; CHECK-NEXT: %x = load volatile i32, i32* %q
  100. ; CHECK-NEXT: %add = sub i32 %y, %x
  101. entry:
  102. br i1 %c, label %header, label %skip
  103. skip:
  104. %y1 = load i32, i32* %p
  105. call void @use(i32 %y1)
  106. br label %header
  107. header:
  108. %x = load volatile i32, i32* %q
  109. %y = load i32, i32* %p
  110. %add = sub i32 %y, %x
  111. %cnd = icmp eq i32 %add, 0
  112. br i1 %cnd, label %exit, label %header
  113. exit:
  114. ret i32 %add
  115. }
  116. ; Another volatile PRE case - two paths through a loop
  117. ; load in preheader, one path read only, one not
  118. define i32 @test8(i1 %b, i1 %c, i32* noalias %p, i32* noalias %q) {
  119. ; CHECK-LABEL: test8
  120. ; CHECK-LABEL: entry
  121. ; CHECK: %y1 = load i32, i32* %p
  122. ; CHECK-LABEL: header:
  123. ; CHECK: %y = phi i32
  124. ; CHECK-NEXT: %x = load volatile i32, i32* %q
  125. ; CHECK-NOT: load
  126. ; CHECK-LABEL: skip.header_crit_edge:
  127. ; CHECK: %y.pre = load i32, i32* %p
  128. entry:
  129. %y1 = load i32, i32* %p
  130. call void @use(i32 %y1)
  131. br label %header
  132. header:
  133. %x = load volatile i32, i32* %q
  134. %y = load i32, i32* %p
  135. call void @use(i32 %y)
  136. br i1 %b, label %skip, label %header
  137. skip:
  138. ; escaping the arguments is explicitly required since we marked
  139. ; them noalias
  140. call void @clobber(i32* %p, i32* %q)
  141. br i1 %c, label %header, label %exit
  142. exit:
  143. %add = sub i32 %y, %x
  144. ret i32 %add
  145. }
  146. declare void @use(i32) readonly
  147. declare void @clobber(i32* %p, i32* %q)