bitcast-alias-function.ll 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. ; RUN: opt -S -instcombine -o - %s | FileCheck %s
  2. target datalayout = "e-p:32:32:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v64:64:64-v128:128:128-a0:0:64"
  3. ; Cases that should be bitcast
  4. ; Test cast between scalars with same bit sizes
  5. @alias_i32_to_f32 = alias bitcast (i32 (i32)* @func_i32 to float (float)*)
  6. ; Test cast between vectors with same number of elements and bit sizes
  7. @alias_v2i32_to_v2f32 = alias bitcast (<2 x i32> (<2 x i32>)* @func_v2i32 to <2 x float> (<2 x float>)*)
  8. ; Test cast from vector to scalar with same number of bits
  9. @alias_v2f32_to_i64 = alias bitcast (i64 (i64)* @func_i64 to <2 x float> (<2 x float>)*)
  10. ; Test cast from scalar to vector with same number of bits
  11. @alias_i64_to_v2f32 = alias bitcast (<2 x float> (<2 x float>)* @func_v2f32 to i64 (i64)*)
  12. ; Test cast between vectors of pointers
  13. @alias_v2i32p_to_v2i64p = alias bitcast (<2 x i32*> (<2 x i32*>)* @func_v2i32p to <2 x i64*> (<2 x i64*>)*)
  14. ; Cases that should be invalid and unchanged
  15. ; Test cast between scalars with different bit sizes
  16. @alias_i64_to_f32 = alias bitcast (i64 (i64)* @func_i64 to float (float)*)
  17. ; Test cast between vectors with different bit sizes but the
  18. ; same number of elements
  19. @alias_v2i64_to_v2f32 = alias bitcast (<2 x i64> (<2 x i64>)* @func_v2i64 to <2 x float> (<2 x float>)*)
  20. ; Test cast between vectors with same number of bits and different
  21. ; numbers of elements
  22. @alias_v2i32_to_v4f32 = alias bitcast (<2 x i32> (<2 x i32>)* @func_v2i32 to <4 x float> (<4 x float>)*)
  23. ; Test cast between scalar and vector with different number of bits
  24. @alias_i64_to_v4f32 = alias bitcast (<4 x float> (<4 x float>)* @func_v4f32 to i64 (i64)*)
  25. ; Test cast between vector and scalar with different number of bits
  26. @alias_v4f32_to_i64 = alias bitcast (i64 (i64)* @func_i64 to <4 x float> (<4 x float>)*)
  27. ; Test cast from scalar to vector of pointers with same number of bits
  28. ; We don't know the pointer size at this point, so this can't be done
  29. @alias_i64_to_v2i32p = alias bitcast (<2 x i32*> (<2 x i32*>)* @func_v2i32p to i64 (i64)*)
  30. ; Test cast between vector of pointers and scalar with different number of bits
  31. @alias_v4i32p_to_i64 = alias bitcast (i64 (i64)* @func_i64 to <4 x i32*> (<4 x i32*>)*)
  32. define internal <2 x i32> @func_v2i32(<2 x i32> %v) noinline nounwind {
  33. entry:
  34. ret <2 x i32> %v
  35. }
  36. define internal <2 x float> @func_v2f32(<2 x float> %v) noinline nounwind {
  37. entry:
  38. ret <2 x float> %v
  39. }
  40. define internal <4 x float> @func_v4f32(<4 x float> %v) noinline nounwind {
  41. entry:
  42. ret <4 x float> %v
  43. }
  44. define internal i32 @func_i32(i32 %v) noinline nounwind {
  45. entry:
  46. ret i32 %v
  47. }
  48. define internal i64 @func_i64(i64 %v) noinline nounwind {
  49. entry:
  50. ret i64 %v
  51. }
  52. define internal <2 x i64> @func_v2i64(<2 x i64> %v) noinline nounwind {
  53. entry:
  54. ret <2 x i64> %v
  55. }
  56. define internal <2 x i32*> @func_v2i32p(<2 x i32*> %v) noinline nounwind {
  57. entry:
  58. ret <2 x i32*> %v
  59. }
  60. ; Valid cases, only bitcast for argument / return type and call underlying function
  61. ; Sizes match, should only bitcast
  62. define void @bitcast_alias_scalar(float* noalias %source, float* noalias %dest) nounwind {
  63. entry:
  64. ; CHECK-LABEL: @bitcast_alias_scalar
  65. ; CHECK: bitcast float* %source to i32*
  66. ; CHECK: load i32, i32*
  67. ; CHECK-NOT: fptoui
  68. ; CHECK-NOT: uitofp
  69. ; CHECK: bitcast float* %dest to i32*
  70. ; CHECK: store i32
  71. %tmp = load float, float* %source, align 8
  72. %call = call float @alias_i32_to_f32(float %tmp) nounwind
  73. store float %call, float* %dest, align 8
  74. ret void
  75. }
  76. ; Sizes match, should only bitcast
  77. define void @bitcast_alias_vector(<2 x float>* noalias %source, <2 x float>* noalias %dest) nounwind {
  78. entry:
  79. ; CHECK-LABEL: @bitcast_alias_vector
  80. ; CHECK: bitcast <2 x float>* %source to <2 x i32>*
  81. ; CHECK: load <2 x i32>, <2 x i32>*
  82. ; CHECK-NOT: fptoui
  83. ; CHECK-NOT: uitofp
  84. ; CHECK: bitcast <2 x float>* %dest to <2 x i32>*
  85. ; CHECK: store <2 x i32>
  86. %tmp = load <2 x float>, <2 x float>* %source, align 8
  87. %call = call <2 x float> @alias_v2i32_to_v2f32(<2 x float> %tmp) nounwind
  88. store <2 x float> %call, <2 x float>* %dest, align 8
  89. ret void
  90. }
  91. ; Sizes match, should only bitcast
  92. define void @bitcast_alias_vector_scalar_same_size(<2 x float>* noalias %source, <2 x float>* noalias %dest) nounwind {
  93. entry:
  94. ; CHECK-LABEL: @bitcast_alias_vector_scalar_same_size
  95. ; CHECK: bitcast <2 x float>* %source to i64*
  96. ; CHECK: load i64, i64*
  97. ; CHECK: %call = call i64 @func_i64
  98. ; CHECK: bitcast <2 x float>* %dest to i64*
  99. ; CHECK: store i64
  100. %tmp = load <2 x float>, <2 x float>* %source, align 8
  101. %call = call <2 x float> @alias_v2f32_to_i64(<2 x float> %tmp) nounwind
  102. store <2 x float> %call, <2 x float>* %dest, align 8
  103. ret void
  104. }
  105. define void @bitcast_alias_scalar_vector_same_size(i64* noalias %source, i64* noalias %dest) nounwind {
  106. entry:
  107. ; CHECK-LABEL: @bitcast_alias_scalar_vector_same_size
  108. ; CHECK: bitcast i64* %source to <2 x float>*
  109. ; CHECK: load <2 x float>, <2 x float>*
  110. ; CHECK: call <2 x float> @func_v2f32
  111. ; CHECK: bitcast i64* %dest to <2 x float>*
  112. ; CHECK: store <2 x float>
  113. %tmp = load i64, i64* %source, align 8
  114. %call = call i64 @alias_i64_to_v2f32(i64 %tmp) nounwind
  115. store i64 %call, i64* %dest, align 8
  116. ret void
  117. }
  118. define void @bitcast_alias_vector_ptrs_same_size(<2 x i64*>* noalias %source, <2 x i64*>* noalias %dest) nounwind {
  119. entry:
  120. ; CHECK-LABEL: @bitcast_alias_vector_ptrs_same_size
  121. ; CHECK: bitcast <2 x i64*>* %source to <2 x i32*>*
  122. ; CHECK: load <2 x i32*>, <2 x i32*>*
  123. ; CHECK: call <2 x i32*> @func_v2i32p
  124. ; CHECK: bitcast <2 x i64*>* %dest to <2 x i32*>*
  125. ; CHECK: store <2 x i32*>
  126. %tmp = load <2 x i64*>, <2 x i64*>* %source, align 8
  127. %call = call <2 x i64*> @alias_v2i32p_to_v2i64p(<2 x i64*> %tmp) nounwind
  128. store <2 x i64*> %call, <2 x i64*>* %dest, align 8
  129. ret void
  130. }
  131. ; Invalid cases:
  132. define void @bitcast_alias_mismatch_scalar_size(float* noalias %source, float* noalias %dest) nounwind {
  133. entry:
  134. ; CHECK-LABEL: @bitcast_alias_mismatch_scalar_size
  135. ; CHECK-NOT: fptoui
  136. ; CHECK: @alias_i64_to_f32
  137. ; CHECK-NOT: uitofp
  138. %tmp = load float, float* %source, align 8
  139. %call = call float @alias_i64_to_f32(float %tmp) nounwind
  140. store float %call, float* %dest, align 8
  141. ret void
  142. }
  143. define void @bitcast_alias_mismatch_vector_element_and_bit_size(<2 x float>* noalias %source, <2 x float>* noalias %dest) nounwind {
  144. entry:
  145. ; CHECK-LABEL: @bitcast_alias_mismatch_vector_element_and_bit_size
  146. ; CHECK-NOT: fptoui <2 x float> %tmp to <2 x i64>
  147. ; CHECK: @alias_v2i64_to_v2f32
  148. ; CHECK-NOT: uitofp <2 x i64> %call to <2 x float>
  149. %tmp = load <2 x float>, <2 x float>* %source, align 8
  150. %call = call <2 x float> @alias_v2i64_to_v2f32(<2 x float> %tmp) nounwind
  151. store <2 x float> %call, <2 x float>* %dest, align 8
  152. ret void
  153. }
  154. define void @bitcast_alias_vector_mismatched_number_elements(<4 x float>* noalias %source, <4 x float>* noalias %dest) nounwind {
  155. entry:
  156. ; CHECK-LABEL: @bitcast_alias_vector_mismatched_number_elements
  157. ; CHECK: %call = call <4 x float> @alias_v2i32_to_v4f32
  158. %tmp = load <4 x float>, <4 x float>* %source, align 8
  159. %call = call <4 x float> @alias_v2i32_to_v4f32(<4 x float> %tmp) nounwind
  160. store <4 x float> %call, <4 x float>* %dest, align 8
  161. ret void
  162. }
  163. define void @bitcast_alias_vector_scalar_mismatched_bit_size(<4 x float>* noalias %source, <4 x float>* noalias %dest) nounwind {
  164. entry:
  165. ; CHECK-LABEL: @bitcast_alias_vector_scalar_mismatched_bit_size
  166. ; CHECK: %call = call <4 x float> @alias_v4f32_to_i64
  167. %tmp = load <4 x float>, <4 x float>* %source, align 8
  168. %call = call <4 x float> @alias_v4f32_to_i64(<4 x float> %tmp) nounwind
  169. store <4 x float> %call, <4 x float>* %dest, align 8
  170. ret void
  171. }
  172. define void @bitcast_alias_vector_ptrs_scalar_mismatched_bit_size(<4 x i32*>* noalias %source, <4 x i32*>* noalias %dest) nounwind {
  173. entry:
  174. ; CHECK-LABEL: @bitcast_alias_vector_ptrs_scalar_mismatched_bit_size
  175. ; CHECK: @alias_v4i32p_to_i64
  176. %tmp = load <4 x i32*>, <4 x i32*>* %source, align 8
  177. %call = call <4 x i32*> @alias_v4i32p_to_i64(<4 x i32*> %tmp) nounwind
  178. store <4 x i32*> %call, <4 x i32*>* %dest, align 8
  179. ret void
  180. }
  181. define void @bitcast_alias_scalar_vector_ptrs_same_size(i64* noalias %source, i64* noalias %dest) nounwind {
  182. entry:
  183. ; CHECK-LABEL: @bitcast_alias_scalar_vector_ptrs_same_size
  184. ; CHECK: @alias_i64_to_v2i32p
  185. %tmp = load i64, i64* %source, align 8
  186. %call = call i64 @alias_i64_to_v2i32p(i64 %tmp) nounwind
  187. store i64 %call, i64* %dest, align 8
  188. ret void
  189. }
  190. define void @bitcast_alias_scalar_vector_mismatched_bit_size(i64* noalias %source, i64* noalias %dest) nounwind {
  191. entry:
  192. ; CHECK-LABEL: @bitcast_alias_scalar_vector_mismatched_bit_size
  193. ; CHECK: call i64 @alias_i64_to_v4f32
  194. %tmp = load i64, i64* %source, align 8
  195. %call = call i64 @alias_i64_to_v4f32(i64 %tmp) nounwind
  196. store i64 %call, i64* %dest, align 8
  197. ret void
  198. }