fcmp.ll 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. ; RUN: opt -S -instcombine < %s | FileCheck %s
  2. declare double @llvm.fabs.f64(double) nounwind readnone
  3. define i1 @test1(float %x, float %y) nounwind {
  4. %ext1 = fpext float %x to double
  5. %ext2 = fpext float %y to double
  6. %cmp = fcmp ogt double %ext1, %ext2
  7. ret i1 %cmp
  8. ; CHECK-LABEL: @test1(
  9. ; CHECK-NEXT: fcmp ogt float %x, %y
  10. }
  11. define i1 @test2(float %a) nounwind {
  12. %ext = fpext float %a to double
  13. %cmp = fcmp ogt double %ext, 1.000000e+00
  14. ret i1 %cmp
  15. ; CHECK-LABEL: @test2(
  16. ; CHECK-NEXT: fcmp ogt float %a, 1.0
  17. }
  18. define i1 @test3(float %a) nounwind {
  19. %ext = fpext float %a to double
  20. %cmp = fcmp ogt double %ext, 0x3FF0000000000001 ; more precision than float.
  21. ret i1 %cmp
  22. ; CHECK-LABEL: @test3(
  23. ; CHECK-NEXT: fpext float %a to double
  24. }
  25. define i1 @test4(float %a) nounwind {
  26. %ext = fpext float %a to double
  27. %cmp = fcmp ogt double %ext, 0x36A0000000000000 ; denormal in float.
  28. ret i1 %cmp
  29. ; CHECK-LABEL: @test4(
  30. ; CHECK-NEXT: fpext float %a to double
  31. }
  32. define i1 @test5(float %a) nounwind {
  33. %neg = fsub float -0.000000e+00, %a
  34. %cmp = fcmp ogt float %neg, 1.000000e+00
  35. ret i1 %cmp
  36. ; CHECK-LABEL: @test5(
  37. ; CHECK-NEXT: fcmp olt float %a, -1.0
  38. }
  39. define i1 @test6(float %x, float %y) nounwind {
  40. %neg1 = fsub float -0.000000e+00, %x
  41. %neg2 = fsub float -0.000000e+00, %y
  42. %cmp = fcmp olt float %neg1, %neg2
  43. ret i1 %cmp
  44. ; CHECK-LABEL: @test6(
  45. ; CHECK-NEXT: fcmp ogt float %x, %y
  46. }
  47. define i1 @test7(float %x) nounwind readnone ssp noredzone {
  48. %ext = fpext float %x to ppc_fp128
  49. %cmp = fcmp ogt ppc_fp128 %ext, 0xM00000000000000000000000000000000
  50. ret i1 %cmp
  51. ; CHECK-LABEL: @test7(
  52. ; CHECK-NEXT: fcmp ogt float %x, 0.000000e+00
  53. }
  54. define float @test8(float %x) nounwind readnone optsize ssp {
  55. %conv = fpext float %x to double
  56. %cmp = fcmp olt double %conv, 0.000000e+00
  57. %conv1 = zext i1 %cmp to i32
  58. %conv2 = sitofp i32 %conv1 to float
  59. ret float %conv2
  60. ; Float comparison to zero shouldn't cast to double.
  61. ; CHECK-LABEL: @test8(
  62. ; CHECK-NEXT: fcmp olt float %x, 0.000000e+00
  63. }
  64. declare double @fabs(double) nounwind readnone
  65. define i32 @test9(double %a) nounwind {
  66. %call = tail call double @fabs(double %a) nounwind
  67. %cmp = fcmp olt double %call, 0.000000e+00
  68. %conv = zext i1 %cmp to i32
  69. ret i32 %conv
  70. ; CHECK-LABEL: @test9(
  71. ; CHECK-NOT: fabs
  72. ; CHECK: ret i32 0
  73. }
  74. define i32 @test9_intrinsic(double %a) nounwind {
  75. %call = tail call double @llvm.fabs.f64(double %a) nounwind
  76. %cmp = fcmp olt double %call, 0.000000e+00
  77. %conv = zext i1 %cmp to i32
  78. ret i32 %conv
  79. ; CHECK-LABEL: @test9_intrinsic(
  80. ; CHECK-NOT: fabs
  81. ; CHECK: ret i32 0
  82. }
  83. define i32 @test10(double %a) nounwind {
  84. %call = tail call double @fabs(double %a) nounwind
  85. %cmp = fcmp ole double %call, 0.000000e+00
  86. %conv = zext i1 %cmp to i32
  87. ret i32 %conv
  88. ; CHECK-LABEL: @test10(
  89. ; CHECK-NOT: fabs
  90. ; CHECK: fcmp oeq double %a, 0.000000e+00
  91. }
  92. define i32 @test10_intrinsic(double %a) nounwind {
  93. %call = tail call double @llvm.fabs.f64(double %a) nounwind
  94. %cmp = fcmp ole double %call, 0.000000e+00
  95. %conv = zext i1 %cmp to i32
  96. ret i32 %conv
  97. ; CHECK-LABEL: @test10_intrinsic(
  98. ; CHECK-NOT: fabs
  99. ; CHECK: fcmp oeq double %a, 0.000000e+00
  100. }
  101. define i32 @test11(double %a) nounwind {
  102. %call = tail call double @fabs(double %a) nounwind
  103. %cmp = fcmp ogt double %call, 0.000000e+00
  104. %conv = zext i1 %cmp to i32
  105. ret i32 %conv
  106. ; CHECK-LABEL: @test11(
  107. ; CHECK-NOT: fabs
  108. ; CHECK: fcmp one double %a, 0.000000e+00
  109. }
  110. define i32 @test11_intrinsic(double %a) nounwind {
  111. %call = tail call double @llvm.fabs.f64(double %a) nounwind
  112. %cmp = fcmp ogt double %call, 0.000000e+00
  113. %conv = zext i1 %cmp to i32
  114. ret i32 %conv
  115. ; CHECK-LABEL: @test11_intrinsic(
  116. ; CHECK-NOT: fabs
  117. ; CHECK: fcmp one double %a, 0.000000e+00
  118. }
  119. define i32 @test12(double %a) nounwind {
  120. %call = tail call double @fabs(double %a) nounwind
  121. %cmp = fcmp oge double %call, 0.000000e+00
  122. %conv = zext i1 %cmp to i32
  123. ret i32 %conv
  124. ; CHECK-LABEL: @test12(
  125. ; CHECK-NOT: fabs
  126. ; CHECK: fcmp ord double %a, 0.000000e+00
  127. }
  128. define i32 @test12_intrinsic(double %a) nounwind {
  129. %call = tail call double @llvm.fabs.f64(double %a) nounwind
  130. %cmp = fcmp oge double %call, 0.000000e+00
  131. %conv = zext i1 %cmp to i32
  132. ret i32 %conv
  133. ; CHECK-LABEL: @test12_intrinsic(
  134. ; CHECK-NOT: fabs
  135. ; CHECK: fcmp ord double %a, 0.000000e+00
  136. }
  137. define i32 @test13(double %a) nounwind {
  138. %call = tail call double @fabs(double %a) nounwind
  139. %cmp = fcmp une double %call, 0.000000e+00
  140. %conv = zext i1 %cmp to i32
  141. ret i32 %conv
  142. ; CHECK-LABEL: @test13(
  143. ; CHECK-NOT: fabs
  144. ; CHECK: fcmp une double %a, 0.000000e+00
  145. }
  146. define i32 @test13_intrinsic(double %a) nounwind {
  147. %call = tail call double @llvm.fabs.f64(double %a) nounwind
  148. %cmp = fcmp une double %call, 0.000000e+00
  149. %conv = zext i1 %cmp to i32
  150. ret i32 %conv
  151. ; CHECK-LABEL: @test13_intrinsic(
  152. ; CHECK-NOT: fabs
  153. ; CHECK: fcmp une double %a, 0.000000e+00
  154. }
  155. define i32 @test14(double %a) nounwind {
  156. %call = tail call double @fabs(double %a) nounwind
  157. %cmp = fcmp oeq double %call, 0.000000e+00
  158. %conv = zext i1 %cmp to i32
  159. ret i32 %conv
  160. ; CHECK-LABEL: @test14(
  161. ; CHECK-NOT: fabs
  162. ; CHECK: fcmp oeq double %a, 0.000000e+00
  163. }
  164. define i32 @test14_intrinsic(double %a) nounwind {
  165. %call = tail call double @llvm.fabs.f64(double %a) nounwind
  166. %cmp = fcmp oeq double %call, 0.000000e+00
  167. %conv = zext i1 %cmp to i32
  168. ret i32 %conv
  169. ; CHECK-LABEL: @test14_intrinsic(
  170. ; CHECK-NOT: fabs
  171. ; CHECK: fcmp oeq double %a, 0.000000e+00
  172. }
  173. define i32 @test15(double %a) nounwind {
  174. %call = tail call double @fabs(double %a) nounwind
  175. %cmp = fcmp one double %call, 0.000000e+00
  176. %conv = zext i1 %cmp to i32
  177. ret i32 %conv
  178. ; CHECK-LABEL: @test15(
  179. ; CHECK-NOT: fabs
  180. ; CHECK: fcmp one double %a, 0.000000e+00
  181. }
  182. define i32 @test15_intrinsic(double %a) nounwind {
  183. %call = tail call double @llvm.fabs.f64(double %a) nounwind
  184. %cmp = fcmp one double %call, 0.000000e+00
  185. %conv = zext i1 %cmp to i32
  186. ret i32 %conv
  187. ; CHECK-LABEL: @test15_intrinsic(
  188. ; CHECK-NOT: fabs
  189. ; CHECK: fcmp one double %a, 0.000000e+00
  190. }
  191. define i32 @test16(double %a) nounwind {
  192. %call = tail call double @fabs(double %a) nounwind
  193. %cmp = fcmp ueq double %call, 0.000000e+00
  194. %conv = zext i1 %cmp to i32
  195. ret i32 %conv
  196. ; CHECK-LABEL: @test16(
  197. ; CHECK-NOT: fabs
  198. ; CHECK: fcmp ueq double %a, 0.000000e+00
  199. }
  200. define i32 @test16_intrinsic(double %a) nounwind {
  201. %call = tail call double @llvm.fabs.f64(double %a) nounwind
  202. %cmp = fcmp ueq double %call, 0.000000e+00
  203. %conv = zext i1 %cmp to i32
  204. ret i32 %conv
  205. ; CHECK-LABEL: @test16_intrinsic(
  206. ; CHECK-NOT: fabs
  207. ; CHECK: fcmp ueq double %a, 0.000000e+00
  208. }
  209. ; Don't crash.
  210. define i32 @test17(double %a, double (double)* %p) nounwind {
  211. %call = tail call double %p(double %a) nounwind
  212. %cmp = fcmp ueq double %call, 0.000000e+00
  213. %conv = zext i1 %cmp to i32
  214. ret i32 %conv
  215. }
  216. ; Can fold fcmp with undef on one side by choosing NaN for the undef
  217. define i32 @test18_undef_unordered(float %a) nounwind {
  218. ; CHECK-LABEL: @test18_undef_unordered
  219. ; CHECK: ret i32 1
  220. %cmp = fcmp ueq float %a, undef
  221. %conv = zext i1 %cmp to i32
  222. ret i32 %conv
  223. }
  224. ; Can fold fcmp with undef on one side by choosing NaN for the undef
  225. define i32 @test18_undef_ordered(float %a) nounwind {
  226. ; CHECK-LABEL: @test18_undef_ordered
  227. ; CHECK: ret i32 0
  228. %cmp = fcmp oeq float %a, undef
  229. %conv = zext i1 %cmp to i32
  230. ret i32 %conv
  231. }
  232. ; Can fold fcmp with undef on both side
  233. ; fcmp u_pred undef, undef -> true
  234. ; fcmp o_pred undef, undef -> false
  235. ; because whatever you choose for the first undef
  236. ; you can choose NaN for the other undef
  237. define i1 @test19_undef_unordered() nounwind {
  238. ; CHECK-LABEL: @test19_undef
  239. ; CHECK: ret i1 true
  240. %cmp = fcmp ueq float undef, undef
  241. ret i1 %cmp
  242. }
  243. define i1 @test19_undef_ordered() nounwind {
  244. ; CHECK-LABEL: @test19_undef
  245. ; CHECK: ret i1 false
  246. %cmp = fcmp oeq float undef, undef
  247. ret i1 %cmp
  248. }