basic.ll 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. ; RUN: opt < %s -float2int -S | FileCheck %s
  2. ;
  3. ; Positive tests
  4. ;
  5. ; CHECK-LABEL: @simple1
  6. ; CHECK: %1 = zext i8 %a to i32
  7. ; CHECK: %2 = add i32 %1, 1
  8. ; CHECK: %3 = trunc i32 %2 to i16
  9. ; CHECK: ret i16 %3
  10. define i16 @simple1(i8 %a) {
  11. %1 = uitofp i8 %a to float
  12. %2 = fadd float %1, 1.0
  13. %3 = fptoui float %2 to i16
  14. ret i16 %3
  15. }
  16. ; CHECK-LABEL: @simple2
  17. ; CHECK: %1 = zext i8 %a to i32
  18. ; CHECK: %2 = sub i32 %1, 1
  19. ; CHECK: %3 = trunc i32 %2 to i8
  20. ; CHECK: ret i8 %3
  21. define i8 @simple2(i8 %a) {
  22. %1 = uitofp i8 %a to float
  23. %2 = fsub float %1, 1.0
  24. %3 = fptoui float %2 to i8
  25. ret i8 %3
  26. }
  27. ; CHECK-LABEL: @simple3
  28. ; CHECK: %1 = zext i8 %a to i32
  29. ; CHECK: %2 = sub i32 %1, 1
  30. ; CHECK: ret i32 %2
  31. define i32 @simple3(i8 %a) {
  32. %1 = uitofp i8 %a to float
  33. %2 = fsub float %1, 1.0
  34. %3 = fptoui float %2 to i32
  35. ret i32 %3
  36. }
  37. ; CHECK-LABEL: @cmp
  38. ; CHECK: %1 = zext i8 %a to i32
  39. ; CHECK: %2 = zext i8 %b to i32
  40. ; CHECK: %3 = icmp slt i32 %1, %2
  41. ; CHECK: ret i1 %3
  42. define i1 @cmp(i8 %a, i8 %b) {
  43. %1 = uitofp i8 %a to float
  44. %2 = uitofp i8 %b to float
  45. %3 = fcmp ult float %1, %2
  46. ret i1 %3
  47. }
  48. ; CHECK-LABEL: @simple4
  49. ; CHECK: %1 = zext i32 %a to i64
  50. ; CHECK: %2 = add i64 %1, 1
  51. ; CHECK: %3 = trunc i64 %2 to i32
  52. ; CHECK: ret i32 %3
  53. define i32 @simple4(i32 %a) {
  54. %1 = uitofp i32 %a to double
  55. %2 = fadd double %1, 1.0
  56. %3 = fptoui double %2 to i32
  57. ret i32 %3
  58. }
  59. ; CHECK-LABEL: @simple5
  60. ; CHECK: %1 = zext i8 %a to i32
  61. ; CHECK: %2 = zext i8 %b to i32
  62. ; CHECK: %3 = add i32 %1, 1
  63. ; CHECK: %4 = mul i32 %3, %2
  64. ; CHECK: ret i32 %4
  65. define i32 @simple5(i8 %a, i8 %b) {
  66. %1 = uitofp i8 %a to float
  67. %2 = uitofp i8 %b to float
  68. %3 = fadd float %1, 1.0
  69. %4 = fmul float %3, %2
  70. %5 = fptoui float %4 to i32
  71. ret i32 %5
  72. }
  73. ; The two chains don't interact - failure of one shouldn't
  74. ; cause failure of the other.
  75. ; CHECK-LABEL: @multi1
  76. ; CHECK: %1 = zext i8 %a to i32
  77. ; CHECK: %2 = zext i8 %b to i32
  78. ; CHECK: %fc = uitofp i8 %c to float
  79. ; CHECK: %x1 = add i32 %1, %2
  80. ; CHECK: %z = fadd float %fc, %d
  81. ; CHECK: %w = fptoui float %z to i32
  82. ; CHECK: %r = add i32 %x1, %w
  83. ; CHECK: ret i32 %r
  84. define i32 @multi1(i8 %a, i8 %b, i8 %c, float %d) {
  85. %fa = uitofp i8 %a to float
  86. %fb = uitofp i8 %b to float
  87. %fc = uitofp i8 %c to float
  88. %x = fadd float %fa, %fb
  89. %y = fptoui float %x to i32
  90. %z = fadd float %fc, %d
  91. %w = fptoui float %z to i32
  92. %r = add i32 %y, %w
  93. ret i32 %r
  94. }
  95. ; CHECK-LABEL: @simple_negzero
  96. ; CHECK: %1 = zext i8 %a to i32
  97. ; CHECK: %2 = add i32 %1, 0
  98. ; CHECK: %3 = trunc i32 %2 to i16
  99. ; CHECK: ret i16 %3
  100. define i16 @simple_negzero(i8 %a) {
  101. %1 = uitofp i8 %a to float
  102. %2 = fadd fast float %1, -0.0
  103. %3 = fptoui float %2 to i16
  104. ret i16 %3
  105. }
  106. ; CHECK-LABEL: @simple_negative
  107. ; CHECK: %1 = sext i8 %call to i32
  108. ; CHECK: %mul1 = mul i32 %1, -3
  109. ; CHECK: %2 = trunc i32 %mul1 to i8
  110. ; CHECK: %conv3 = sext i8 %2 to i32
  111. ; CHECK: ret i32 %conv3
  112. define i32 @simple_negative(i8 %call) {
  113. %conv1 = sitofp i8 %call to float
  114. %mul = fmul float %conv1, -3.000000e+00
  115. %conv2 = fptosi float %mul to i8
  116. %conv3 = sext i8 %conv2 to i32
  117. ret i32 %conv3
  118. }
  119. ;
  120. ; Negative tests
  121. ;
  122. ; CHECK-LABEL: @neg_multi1
  123. ; CHECK: %fa = uitofp i8 %a to float
  124. ; CHECK: %fc = uitofp i8 %c to float
  125. ; CHECK: %x = fadd float %fa, %fc
  126. ; CHECK: %y = fptoui float %x to i32
  127. ; CHECK: %z = fadd float %fc, %d
  128. ; CHECK: %w = fptoui float %z to i32
  129. ; CHECK: %r = add i32 %y, %w
  130. ; CHECK: ret i32 %r
  131. ; The two chains intersect, which means because one fails, no
  132. ; transform can occur.
  133. define i32 @neg_multi1(i8 %a, i8 %b, i8 %c, float %d) {
  134. %fa = uitofp i8 %a to float
  135. %fc = uitofp i8 %c to float
  136. %x = fadd float %fa, %fc
  137. %y = fptoui float %x to i32
  138. %z = fadd float %fc, %d
  139. %w = fptoui float %z to i32
  140. %r = add i32 %y, %w
  141. ret i32 %r
  142. }
  143. ; CHECK-LABEL: @neg_muld
  144. ; CHECK: %fa = uitofp i32 %a to double
  145. ; CHECK: %fb = uitofp i32 %b to double
  146. ; CHECK: %mul = fmul double %fa, %fb
  147. ; CHECK: %r = fptoui double %mul to i64
  148. ; CHECK: ret i64 %r
  149. ; The i32 * i32 = i64, which has 64 bits, which is greater than the 52 bits
  150. ; that can be exactly represented in a double.
  151. define i64 @neg_muld(i32 %a, i32 %b) {
  152. %fa = uitofp i32 %a to double
  153. %fb = uitofp i32 %b to double
  154. %mul = fmul double %fa, %fb
  155. %r = fptoui double %mul to i64
  156. ret i64 %r
  157. }
  158. ; CHECK-LABEL: @neg_mulf
  159. ; CHECK: %fa = uitofp i16 %a to float
  160. ; CHECK: %fb = uitofp i16 %b to float
  161. ; CHECK: %mul = fmul float %fa, %fb
  162. ; CHECK: %r = fptoui float %mul to i32
  163. ; CHECK: ret i32 %r
  164. ; The i16 * i16 = i32, which can't be represented in a float, but can in a
  165. ; double. This should fail, as the written code uses floats, not doubles so
  166. ; the original result may be inaccurate.
  167. define i32 @neg_mulf(i16 %a, i16 %b) {
  168. %fa = uitofp i16 %a to float
  169. %fb = uitofp i16 %b to float
  170. %mul = fmul float %fa, %fb
  171. %r = fptoui float %mul to i32
  172. ret i32 %r
  173. }
  174. ; CHECK-LABEL: @neg_cmp
  175. ; CHECK: %1 = uitofp i8 %a to float
  176. ; CHECK: %2 = uitofp i8 %b to float
  177. ; CHECK: %3 = fcmp false float %1, %2
  178. ; CHECK: ret i1 %3
  179. ; "false" doesn't have an icmp equivalent.
  180. define i1 @neg_cmp(i8 %a, i8 %b) {
  181. %1 = uitofp i8 %a to float
  182. %2 = uitofp i8 %b to float
  183. %3 = fcmp false float %1, %2
  184. ret i1 %3
  185. }
  186. ; CHECK-LABEL: @neg_div
  187. ; CHECK: %1 = uitofp i8 %a to float
  188. ; CHECK: %2 = fdiv float %1, 1.0
  189. ; CHECK: %3 = fptoui float %2 to i16
  190. ; CHECK: ret i16 %3
  191. ; Division isn't a supported operator.
  192. define i16 @neg_div(i8 %a) {
  193. %1 = uitofp i8 %a to float
  194. %2 = fdiv float %1, 1.0
  195. %3 = fptoui float %2 to i16
  196. ret i16 %3
  197. }
  198. ; CHECK-LABEL: @neg_remainder
  199. ; CHECK: %1 = uitofp i8 %a to float
  200. ; CHECK: %2 = fadd float %1, 1.2
  201. ; CHECK: %3 = fptoui float %2 to i16
  202. ; CHECK: ret i16 %3
  203. ; 1.2 is not an integer.
  204. define i16 @neg_remainder(i8 %a) {
  205. %1 = uitofp i8 %a to float
  206. %2 = fadd float %1, 1.25
  207. %3 = fptoui float %2 to i16
  208. ret i16 %3
  209. }
  210. ; CHECK-LABEL: @neg_toolarge
  211. ; CHECK: %1 = uitofp i80 %a to fp128
  212. ; CHECK: %2 = fadd fp128 %1, %1
  213. ; CHECK: %3 = fptoui fp128 %2 to i80
  214. ; CHECK: ret i80 %3
  215. ; i80 > i64, which is the largest bitwidth handleable by default.
  216. define i80 @neg_toolarge(i80 %a) {
  217. %1 = uitofp i80 %a to fp128
  218. %2 = fadd fp128 %1, %1
  219. %3 = fptoui fp128 %2 to i80
  220. ret i80 %3
  221. }
  222. ; CHECK-LABEL: @neg_calluser
  223. ; CHECK: sitofp
  224. ; CHECK: fcmp
  225. ; The sequence %1..%3 cannot be converted because %4 uses %2.
  226. define i32 @neg_calluser(i32 %value) {
  227. %1 = sitofp i32 %value to double
  228. %2 = fadd double %1, 1.0
  229. %3 = fcmp olt double %2, 0.000000e+00
  230. %4 = tail call double @g(double %2)
  231. %5 = fptosi double %4 to i32
  232. %6 = zext i1 %3 to i32
  233. %7 = add i32 %6, %5
  234. ret i32 %7
  235. }
  236. declare double @g(double)