smul.carbon 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. //
  5. // INCLUDE-FILE: toolchain/testing/testdata/min_prelude/int.carbon
  6. //
  7. // AUTOUPDATE
  8. // TIP: To test this file alone, run:
  9. // TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/builtins/int/smul.carbon
  10. // TIP: To dump output, run:
  11. // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/builtins/int/smul.carbon
  12. // --- i32.carbon
  13. library "[[@TEST_NAME]]";
  14. fn Mul(a: i32, b: i32) -> i32 = "int.smul";
  15. class Expect(N:! i32) {}
  16. fn Test(N:! i32) -> Expect(N) { return {}; }
  17. fn F() {
  18. Test(Mul(0, 0)) as Expect(0);
  19. Test(Mul(0, 3)) as Expect(0);
  20. Test(Mul(1, 2)) as Expect(2);
  21. Test(Mul(3, 2)) as Expect(6);
  22. Test(Mul(0x7FFF_FFFF, 1)) as Expect(0x7FFF_FFFF);
  23. Test(Mul(0x7FFF_FFFF, -1)) as Expect(-0x7FFF_FFFF);
  24. }
  25. fn RuntimeCallIsValid(a: i32, b: i32) -> i32 {
  26. //@dump-sem-ir-begin
  27. return Mul(a, b);
  28. //@dump-sem-ir-end
  29. }
  30. // --- literal.carbon
  31. library "[[@TEST_NAME]]";
  32. fn Mul(a: Core.IntLiteral(), b: Core.IntLiteral()) -> Core.IntLiteral() = "int.smul";
  33. class Expect(N:! Core.IntLiteral()) {}
  34. fn Test(N:! Core.IntLiteral()) -> Expect(N) { return {}; }
  35. fn F() {
  36. Test(Mul(0, 0)) as Expect(0);
  37. Test(Mul(0, 3)) as Expect(0);
  38. Test(Mul(1, 2)) as Expect(2);
  39. Test(Mul(3, 2)) as Expect(6);
  40. Test(Mul(0x7FFF_FFFF, 1)) as Expect(0x7FFF_FFFF);
  41. Test(Mul(0x7FFF_FFFF, -1)) as Expect(-0x7FFF_FFFF);
  42. // Test some cases that might -- but shouldn't -- overflow.
  43. Test(Mul(0x8000_0000_0000_0000, 1)) as Expect(0x8000_0000_0000_0000);
  44. Test(Mul(0x8000_0000_0000_0000, -1)) as Expect(-0x8000_0000_0000_0000);
  45. Test(Mul(-0x8000_0000_0000_0000, 1)) as Expect(-0x8000_0000_0000_0000);
  46. Test(Mul(-0x8000_0000_0000_0000, -1)) as Expect(0x8000_0000_0000_0000);
  47. Test(Mul(-0x8000_0000_0000_0000, -1)) as Expect(0x8000_0000_0000_0000);
  48. Test(Mul(-0x8000_0000_0000_0000, -0x8000_0000_0000_0000))
  49. as Expect(0x4000_0000_0000_0000_0000_0000_0000_0000);
  50. }
  51. // --- fail_overflow.carbon
  52. library "[[@TEST_NAME]]";
  53. fn Mul(a: i32, b: i32) -> i32 = "int.smul";
  54. let a: i32 = Mul(0x7FFF, 0x10000);
  55. // CHECK:STDERR: fail_overflow.carbon:[[@LINE+4]]:14: error: integer overflow in calculation `32768 * 65536` [CompileTimeIntegerOverflow]
  56. // CHECK:STDERR: let b: i32 = Mul(0x8000, 0x10000);
  57. // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~
  58. // CHECK:STDERR:
  59. let b: i32 = Mul(0x8000, 0x10000);
  60. // CHECK:STDOUT: --- i32.carbon
  61. // CHECK:STDOUT:
  62. // CHECK:STDOUT: constants {
  63. // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
  64. // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
  65. // CHECK:STDOUT: %Mul.type: type = fn_type @Mul [concrete]
  66. // CHECK:STDOUT: %Mul: %Mul.type = struct_value () [concrete]
  67. // CHECK:STDOUT: }
  68. // CHECK:STDOUT:
  69. // CHECK:STDOUT: imports {
  70. // CHECK:STDOUT: }
  71. // CHECK:STDOUT:
  72. // CHECK:STDOUT: fn @RuntimeCallIsValid(%a.param: %i32, %b.param: %i32) -> %i32 {
  73. // CHECK:STDOUT: !entry:
  74. // CHECK:STDOUT: %Mul.ref: %Mul.type = name_ref Mul, file.%Mul.decl [concrete = constants.%Mul]
  75. // CHECK:STDOUT: %a.ref: %i32 = name_ref a, %a
  76. // CHECK:STDOUT: %b.ref: %i32 = name_ref b, %b
  77. // CHECK:STDOUT: %int.smul: init %i32 = call %Mul.ref(%a.ref, %b.ref)
  78. // CHECK:STDOUT: %.loc20_19.1: %i32 = value_of_initializer %int.smul
  79. // CHECK:STDOUT: %.loc20_19.2: %i32 = converted %int.smul, %.loc20_19.1
  80. // CHECK:STDOUT: return %.loc20_19.2
  81. // CHECK:STDOUT: }
  82. // CHECK:STDOUT: