overflow-mul.ll 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. ; RUN: opt -S -instcombine < %s | FileCheck %s
  2. ; return mul(zext x, zext y) > MAX
  3. define i32 @pr4917_1(i32 %x, i32 %y) nounwind {
  4. ; CHECK-LABEL: @pr4917_1(
  5. entry:
  6. %l = zext i32 %x to i64
  7. %r = zext i32 %y to i64
  8. ; CHECK-NOT: zext i32
  9. %mul64 = mul i64 %l, %r
  10. ; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y)
  11. %overflow = icmp ugt i64 %mul64, 4294967295
  12. ; CHECK: extractvalue { i32, i1 } [[MUL]], 1
  13. %retval = zext i1 %overflow to i32
  14. ret i32 %retval
  15. }
  16. ; return mul(zext x, zext y) >= MAX+1
  17. define i32 @pr4917_1a(i32 %x, i32 %y) nounwind {
  18. ; CHECK-LABEL: @pr4917_1a(
  19. entry:
  20. %l = zext i32 %x to i64
  21. %r = zext i32 %y to i64
  22. ; CHECK-NOT: zext i32
  23. %mul64 = mul i64 %l, %r
  24. ; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y)
  25. %overflow = icmp uge i64 %mul64, 4294967296
  26. ; CHECK: extractvalue { i32, i1 } [[MUL]], 1
  27. %retval = zext i1 %overflow to i32
  28. ret i32 %retval
  29. }
  30. ; mul(zext x, zext y) > MAX
  31. ; mul(x, y) is used
  32. define i32 @pr4917_2(i32 %x, i32 %y) nounwind {
  33. ; CHECK-LABEL: @pr4917_2(
  34. entry:
  35. %l = zext i32 %x to i64
  36. %r = zext i32 %y to i64
  37. ; CHECK-NOT: zext i32
  38. %mul64 = mul i64 %l, %r
  39. ; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y)
  40. %overflow = icmp ugt i64 %mul64, 4294967295
  41. ; CHECK-DAG: [[VAL:%.*]] = extractvalue { i32, i1 } [[MUL]], 0
  42. %mul32 = trunc i64 %mul64 to i32
  43. ; CHECK-DAG: [[OVFL:%.*]] = extractvalue { i32, i1 } [[MUL]], 1
  44. %retval = select i1 %overflow, i32 %mul32, i32 111
  45. ; CHECK: select i1 [[OVFL]], i32 [[VAL]]
  46. ret i32 %retval
  47. }
  48. ; return mul(zext x, zext y) > MAX
  49. ; mul is used in non-truncate
  50. define i64 @pr4917_3(i32 %x, i32 %y) nounwind {
  51. ; CHECK-LABEL: @pr4917_3(
  52. entry:
  53. %l = zext i32 %x to i64
  54. %r = zext i32 %y to i64
  55. %mul64 = mul i64 %l, %r
  56. ; CHECK-NOT: umul.with.overflow.i32
  57. %overflow = icmp ugt i64 %mul64, 4294967295
  58. %retval = select i1 %overflow, i64 %mul64, i64 111
  59. ret i64 %retval
  60. }
  61. ; return mul(zext x, zext y) <= MAX
  62. define i32 @pr4917_4(i32 %x, i32 %y) nounwind {
  63. ; CHECK-LABEL: @pr4917_4(
  64. entry:
  65. %l = zext i32 %x to i64
  66. %r = zext i32 %y to i64
  67. ; CHECK-NOT: zext i32
  68. %mul64 = mul i64 %l, %r
  69. ; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y)
  70. %overflow = icmp ule i64 %mul64, 4294967295
  71. ; CHECK: extractvalue { i32, i1 } [[MUL]], 1
  72. ; CHECK: xor
  73. %retval = zext i1 %overflow to i32
  74. ret i32 %retval
  75. }
  76. ; return mul(zext x, zext y) < MAX+1
  77. define i32 @pr4917_4a(i32 %x, i32 %y) nounwind {
  78. ; CHECK-LABEL: @pr4917_4a(
  79. entry:
  80. %l = zext i32 %x to i64
  81. %r = zext i32 %y to i64
  82. ; CHECK-NOT: zext i32
  83. %mul64 = mul i64 %l, %r
  84. ; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y)
  85. %overflow = icmp ult i64 %mul64, 4294967296
  86. ; CHECK: extractvalue { i32, i1 } [[MUL]], 1
  87. ; CHECK: xor
  88. %retval = zext i1 %overflow to i32
  89. ret i32 %retval
  90. }
  91. ; operands of mul are of different size
  92. define i32 @pr4917_5(i32 %x, i8 %y) nounwind {
  93. ; CHECK-LABEL: @pr4917_5(
  94. entry:
  95. %l = zext i32 %x to i64
  96. %r = zext i8 %y to i64
  97. ; CHECK: [[Y:%.*]] = zext i8 %y to i32
  98. %mul64 = mul i64 %l, %r
  99. %overflow = icmp ugt i64 %mul64, 4294967295
  100. %mul32 = trunc i64 %mul64 to i32
  101. ; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 [[Y]])
  102. ; CHECK-DAG: [[VAL:%.*]] = extractvalue { i32, i1 } [[MUL]], 0
  103. ; CHECK-DAG: [[OVFL:%.*]] = extractvalue { i32, i1 } [[MUL]], 1
  104. %retval = select i1 %overflow, i32 %mul32, i32 111
  105. ; CHECK: select i1 [[OVFL]], i32 [[VAL]]
  106. ret i32 %retval
  107. }
  108. ; mul(zext x, zext y) != zext trunc mul
  109. define i32 @pr4918_1(i32 %x, i32 %y) nounwind {
  110. ; CHECK-LABEL: @pr4918_1(
  111. entry:
  112. %l = zext i32 %x to i64
  113. %r = zext i32 %y to i64
  114. %mul64 = mul i64 %l, %r
  115. ; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y)
  116. %part32 = trunc i64 %mul64 to i32
  117. %part64 = zext i32 %part32 to i64
  118. %overflow = icmp ne i64 %mul64, %part64
  119. ; CHECK: [[OVFL:%.*]] = extractvalue { i32, i1 } [[MUL:%.*]], 1
  120. %retval = zext i1 %overflow to i32
  121. ret i32 %retval
  122. }
  123. ; mul(zext x, zext y) == zext trunc mul
  124. define i32 @pr4918_2(i32 %x, i32 %y) nounwind {
  125. ; CHECK-LABEL: @pr4918_2(
  126. entry:
  127. %l = zext i32 %x to i64
  128. %r = zext i32 %y to i64
  129. %mul64 = mul i64 %l, %r
  130. ; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y)
  131. %part32 = trunc i64 %mul64 to i32
  132. %part64 = zext i32 %part32 to i64
  133. %overflow = icmp eq i64 %mul64, %part64
  134. ; CHECK: extractvalue { i32, i1 } [[MUL]]
  135. %retval = zext i1 %overflow to i32
  136. ; CHECK: xor
  137. ret i32 %retval
  138. }
  139. ; zext trunc mul != mul(zext x, zext y)
  140. define i32 @pr4918_3(i32 %x, i32 %y) nounwind {
  141. ; CHECK-LABEL: @pr4918_3(
  142. entry:
  143. %l = zext i32 %x to i64
  144. %r = zext i32 %y to i64
  145. %mul64 = mul i64 %l, %r
  146. ; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y)
  147. %part32 = trunc i64 %mul64 to i32
  148. %part64 = zext i32 %part32 to i64
  149. %overflow = icmp ne i64 %part64, %mul64
  150. ; CHECK: extractvalue { i32, i1 } [[MUL]], 1
  151. %retval = zext i1 %overflow to i32
  152. ret i32 %retval
  153. }
  154. define <4 x i32> @pr20113(<4 x i16> %a, <4 x i16> %b) {
  155. ; CHECK-LABEL: @pr20113
  156. ; CHECK-NOT: mul.with.overflow
  157. ; CHECK: ret
  158. %vmovl.i.i726 = zext <4 x i16> %a to <4 x i32>
  159. %vmovl.i.i712 = zext <4 x i16> %b to <4 x i32>
  160. %mul.i703 = mul <4 x i32> %vmovl.i.i712, %vmovl.i.i726
  161. %tmp = icmp sge <4 x i32> %mul.i703, zeroinitializer
  162. %vcgez.i = sext <4 x i1> %tmp to <4 x i32>
  163. ret <4 x i32> %vcgez.i
  164. }
  165. ; The last test needs this weird datalayout.
  166. target datalayout = "i32:8:8"
  167. ; Without it, InstCombine will align the pointed on 4 Bytes
  168. ; The KnownBitsZero that result from the alignment allows to
  169. ; turn:
  170. ; and i32 %mul, 255
  171. ; to:
  172. ; and i32 %mul, 252
  173. ; The mask is no longer in the form 2^n-1 and this prevents the transformation.
  174. @pr21445_data = external global i32
  175. define i1 @pr21445(i8 %a) {
  176. ; CHECK-LABEL: @pr21445(
  177. ; CHECK-NEXT: %[[umul:.*]] = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 %a, i8 ptrtoint (i32* @pr21445_data to i8))
  178. ; CHECK-NEXT: %[[cmp:.*]] = extractvalue { i8, i1 } %[[umul]], 1
  179. ; CHECK-NEXT: ret i1 %[[cmp]]
  180. %ext = zext i8 %a to i32
  181. %mul = mul i32 %ext, zext (i8 ptrtoint (i32* @pr21445_data to i8) to i32)
  182. %and = and i32 %mul, 255
  183. %cmp = icmp ne i32 %mul, %and
  184. ret i1 %cmp
  185. }