mgehre-amd created this revision.
mgehre-amd added reviewers: aaron.ballman, erichkeane.
Herald added subscribers: luke957, s.egerton, mstorsjo, simoncook,
fedor.sergeev, dschuff.
Herald added a project: All.
mgehre-amd requested review of this revision.
Herald added subscribers: pcwang-thead, aheejin.
Herald added a project: clang.
According to the RFC [0], this review contains the clang parts of large integer
divison for _BitInt.
It contains the following parts:
- Driver: Gnu, MinGW: Link libbitint when available
- clang/Basic/TargetInfo: Increase getMaxBitIntWidth to
llvm::IntegerType::MAX_INT_BITS
- Sema: Diagnose when converting _BitInt to/from floating point for bit width >
128 because that breaks in the backend
- Lex: Speedup parsing of large integer literals with a power-of-two radix, so
parsing a hex literal with 2097152 digits (=MAX_INT_BITS) doesn't take forever
[0]
https://discourse.llvm.org/t/rfc-add-support-for-division-of-large-bitint-builtins-selectiondag-globalisel-clang/60329
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D122234
Files:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Basic/TargetInfo.h
clang/include/clang/Sema/Sema.h
clang/lib/Driver/ToolChains/CommonArgs.cpp
clang/lib/Driver/ToolChains/CommonArgs.h
clang/lib/Driver/ToolChains/Gnu.cpp
clang/lib/Driver/ToolChains/MinGW.cpp
clang/lib/Lex/LiteralSupport.cpp
clang/lib/Sema/Sema.cpp
clang/lib/Sema/SemaCast.cpp
clang/test/CodeGen/ext-int-cc.c
clang/test/Driver/linux-ld.c
clang/test/Lexer/bitint-constants.c
clang/test/Preprocessor/init-aarch64.c
clang/test/Preprocessor/init.c
clang/test/Sema/ext-int.c
clang/test/SemaCXX/ext-int.cpp
Index: clang/test/SemaCXX/ext-int.cpp
===================================================================
--- clang/test/SemaCXX/ext-int.cpp
+++ clang/test/SemaCXX/ext-int.cpp
@@ -17,7 +17,7 @@
unsigned _BitInt(5) e = 5;
_BitInt(5) unsigned f;
- _BitInt(-3) g; // expected-error{{signed _BitInt of bit sizes greater than 128 not supported}}
+ _BitInt(-3) g; // expected-error{{signed _BitInt of bit sizes greater than 8388608 not supported}}
_BitInt(0) h; // expected-error{{signed _BitInt must have a bit size of at least 2}}
_BitInt(1) i; // expected-error{{signed _BitInt must have a bit size of at least 2}}
_BitInt(2) j;;
@@ -29,12 +29,12 @@
constexpr _BitInt(7) o = 33;
// Check imposed max size.
- _BitInt(129) p; // expected-error {{signed _BitInt of bit sizes greater than 128 not supported}}
- unsigned _BitInt(0xFFFFFFFFFF) q; // expected-error {{unsigned _BitInt of bit sizes greater than 128 not supported}}
+ _BitInt(8388609) p; // expected-error {{signed _BitInt of bit sizes greater than 8388608 not supported}}
+ unsigned _BitInt(0xFFFFFFFFFF) q; // expected-error {{unsigned _BitInt of bit sizes greater than 8388608 not supported}}
// Ensure template params are instantiated correctly.
- // expected-error@5{{signed _BitInt of bit sizes greater than 128 not supported}}
- // expected-error@6{{unsigned _BitInt of bit sizes greater than 128 not supported}}
+ // expected-error@5{{signed _BitInt of bit sizes greater than 8388608 not supported}}
+ // expected-error@6{{unsigned _BitInt of bit sizes greater than 8388608 not supported}}
// expected-note@+1{{in instantiation of template class }}
HasExtInt<-1> r;
// expected-error@5{{signed _BitInt must have a bit size of at least 2}}
@@ -285,3 +285,16 @@
void FromPaper2(_BitInt(8) a1, _BitInt(24) a2) {
static_assert(is_same<decltype(a1 * (_BitInt(32))a2), _BitInt(32)>::value, "");
}
+
+void LargeBitIntToFloat(_BitInt(129) a) {
+ float fa = a; // expected-error {{cannot convert '_BitInt' operands of more than 128 bits to floating point}}
+ fa = static_cast<float>(a); // expected-error {{cannot convert '_BitInt' operands of more than 128 bits to floating point}}
+ fa = a + 0.1; // expected-error {{cannot convert '_BitInt' operands of more than 128 bits to floating point}}
+}
+
+_BitInt(129) LargeBitIntFromFloat(float f) {
+ _BitInt(129) a = f; // expected-error {{cannot convert floating point operands to a '_BitInt' of more than 128 bits}}
+ a = f; // expected-error {{cannot convert floating point operands to a '_BitInt' of more than 128 bits}}
+ a = static_cast<_BitInt(129)>(f); // expected-error {{cannot convert floating point operands to a '_BitInt' of more than 128 bits}}
+ return f; // expected-error {{cannot convert floating point operands to a '_BitInt' of more than 128 bits}}
+}
Index: clang/test/Sema/ext-int.c
===================================================================
--- clang/test/Sema/ext-int.c
+++ clang/test/Sema/ext-int.c
@@ -73,3 +73,16 @@
void FromPaper2(_BitInt(8) a1, _BitInt(24) a2) {
_Static_assert(EXPR_HAS_TYPE(a1 * (_BitInt(32))a2, _BitInt(32)), "");
}
+
+
+void LargeBitIntToFloat(_BitInt(129) a) {
+ float fa = a; // expected-error {{cannot convert '_BitInt' operands of more than 128 bits to floating point}}
+ fa = (float)a; // expected-error {{cannot convert '_BitInt' operands of more than 128 bits to floating point}}
+ fa = a + 0.1; // expected-error {{cannot convert '_BitInt' operands of more than 128 bits to floating point}}
+}
+
+_BitInt(129) LargeBitIntFromFloat(float f) {
+ _BitInt(129) b = f; // expected-error {{cannot convert floating point operands to a '_BitInt' of more than 128 bits}}
+ b = (_BitInt(129))f; // expected-error {{cannot convert floating point operands to a '_BitInt' of more than 128 bits}}
+ return f; // expected-error {{cannot convert floating point operands to a '_BitInt' of more than 128 bits}}
+}
Index: clang/test/Preprocessor/init.c
===================================================================
--- clang/test/Preprocessor/init.c
+++ clang/test/Preprocessor/init.c
@@ -1515,7 +1515,7 @@
// WEBASSEMBLY-NEXT:#define __ATOMIC_RELEASE 3
// WEBASSEMBLY-NEXT:#define __ATOMIC_SEQ_CST 5
// WEBASSEMBLY-NEXT:#define __BIGGEST_ALIGNMENT__ 16
-// WEBASSEMBLY-NEXT:#define __BITINT_MAXWIDTH__ 128
+// WEBASSEMBLY-NEXT:#define __BITINT_MAXWIDTH__ 8388608
// WEBASSEMBLY-NEXT:#define __BOOL_WIDTH__ 8
// WEBASSEMBLY-NEXT:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
// WEBASSEMBLY-NEXT:#define __CHAR16_TYPE__ unsigned short
Index: clang/test/Preprocessor/init-aarch64.c
===================================================================
--- clang/test/Preprocessor/init-aarch64.c
+++ clang/test/Preprocessor/init-aarch64.c
@@ -40,7 +40,7 @@
// AARCH64-NEXT: #define __ATOMIC_SEQ_CST 5
// AARCH64: #define __BIGGEST_ALIGNMENT__ 16
// AARCH64_BE-NEXT: #define __BIG_ENDIAN__ 1
-// AARCH64-NEXT: #define __BITINT_MAXWIDTH__ 128
+// AARCH64-NEXT: #define __BITINT_MAXWIDTH__ 8388608
// AARCH64-NEXT: #define __BOOL_WIDTH__ 8
// AARCH64_BE-NEXT: #define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
// AARCH64_LE-NEXT: #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
Index: clang/test/Lexer/bitint-constants.c
===================================================================
--- clang/test/Lexer/bitint-constants.c
+++ clang/test/Lexer/bitint-constants.c
@@ -137,10 +137,28 @@
// the width of BITINT_MAXWIDTH. When this value changes in the future, the
// test cases should pick a new value that can't be represented by a _BitInt,
// but also add a test case that a 129-bit literal still behaves as-expected.
- _Static_assert(__BITINT_MAXWIDTH__ <= 128,
- "Need to pick a bigger constant for the test case below.");
- 0xFFFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF'1wb; // expected-error {{integer literal is too large to be represented in any signed integer type}}
- 0xFFFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF'1uwb; // expected-error {{integer literal is too large to be represented in any integer type}}
+ 0xFFFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF'1wb; // 129 bits are fine
+ 0xFFFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF'1uwb; // 129 bit unsigned are fine
+
+ #define CONCAT(X,Y) X ## Y
+ #define REPEAT2(X) CONCAT(X,X)
+ #define REPEAT4(X) REPEAT2(REPEAT2(X))
+ #define REPEAT16(X) REPEAT4(REPEAT4(X))
+ #define REPEAT256(X) REPEAT16(REPEAT16(X))
+ #define REPEAT65536(X) REPEAT256(REPEAT256(X))
+ #define REPEAT2097152(X) REPEAT65536(REPEAT16(REPEAT2(X)))
+ #define _LITERAL(X, Suffix) 0x ## X ## Suffix
+ #define LITERAL(X, Suffix) _LITERAL(X, Suffix)
+
+ _Static_assert(__BITINT_MAXWIDTH__ <= 8388608,
+ "Need to pick a bigger constant for the test case below.");
+
+ // 8388608 bits are represented by 2097152 hex digits
+ LITERAL(REPEAT2097152(7), wb); // 262143 bits plus one sign bit are fine
+ LITERAL(REPEAT2097152(F), wb); // expected-error {{integer literal is too large to be represented in any signed integer type}}
+
+ LITERAL(REPEAT2097152(F), uwb); // 262144 bits unsigned are fine
+ LITERAL(REPEAT2097152(F), 1uwb); // expected-error {{integer literal is too large to be represented in any integer type}}
}
void TestTypes(void) {
Index: clang/test/Driver/linux-ld.c
===================================================================
--- clang/test/Driver/linux-ld.c
+++ clang/test/Driver/linux-ld.c
@@ -174,7 +174,7 @@
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-CLANG-NO-LIBGCC-STATIC %s
// CHECK-CLANG-NO-LIBGCC-STATIC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
-// CHECK-CLANG-NO-LIBGCC-STATIC: "--start-group" "-lgcc" "-lgcc_eh" "-lc" "--end-group"
+// CHECK-CLANG-NO-LIBGCC-STATIC: "--start-group" "{{[^"]*}}/libclang_rt.bitint{{[^"]*}}" "-lgcc" "-lgcc_eh" "-lc" "--end-group"
//
// RUN: %clang -static-pie -no-canonical-prefixes %s -### -o %t.o 2>&1 \
// RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \
@@ -189,7 +189,7 @@
// CHECK-CLANG-LD-STATIC-PIE: "text"
// CHECK-CLANG-LD-STATIC-PIE: "-m" "elf_x86_64"
// CHECK-CLANG-LD-STATIC-PIE: "{{.*}}rcrt1.o"
-// CHECK-CLANG-LD-STATIC-PIE: "--start-group" "-lgcc" "-lgcc_eh" "-lc" "--end-group"
+// CHECK-CLANG-LD-STATIC-PIE: "--start-group" "{{[^"]*}}/libclang_rt.bitint{{[^"]*}}" "-lgcc" "-lgcc_eh" "-lc" "--end-group"
//
// RUN: %clang -static-pie -pie -no-canonical-prefixes %s -no-pie -### -o %t.o 2>&1 \
// RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \
@@ -204,7 +204,7 @@
// CHECK-CLANG-LD-STATIC-PIE-PIE: "text"
// CHECK-CLANG-LD-STATIC-PIE-PIE: "-m" "elf_x86_64"
// CHECK-CLANG-LD-STATIC-PIE-PIE: "{{.*}}rcrt1.o"
-// CHECK-CLANG-LD-STATIC-PIE-PIE: "--start-group" "-lgcc" "-lgcc_eh" "-lc" "--end-group"
+// CHECK-CLANG-LD-STATIC-PIE-PIE: "--start-group" "{{[^"]*}}/libclang_rt.bitint{{[^"]*}}" "-lgcc" "-lgcc_eh" "-lc" "--end-group"
//
// RUN: %clang -static-pie -static -no-canonical-prefixes %s -no-pie -### -o %t.o 2>&1 \
// RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \
@@ -219,7 +219,7 @@
// CHECK-CLANG-LD-STATIC-PIE-STATIC: "text"
// CHECK-CLANG-LD-STATIC-PIE-STATIC: "-m" "elf_x86_64"
// CHECK-CLANG-LD-STATIC-PIE-STATIC: "{{.*}}rcrt1.o"
-// CHECK-CLANG-LD-STATIC-PIE-STATIC: "--start-group" "-lgcc" "-lgcc_eh" "-lc" "--end-group"
+// CHECK-CLANG-LD-STATIC-PIE-STATIC: "--start-group" "{{[^"]*}}/libclang_rt.bitint{{[^"]*}}" "-lgcc" "-lgcc_eh" "-lc" "--end-group"
//
// RUN: %clang -static-pie -nopie -no-canonical-prefixes %s -no-pie -### -o %t.o 2>&1 \
// RUN: --target=x86_64-unknown-linux -rtlib=platform \
@@ -318,7 +318,7 @@
// CHECK-LD-64-STATIC: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/10.2.0/../../../../x86_64-unknown-linux/lib"
// CHECK-LD-64-STATIC: "-L[[SYSROOT]]/lib"
// CHECK-LD-64-STATIC: "-L[[SYSROOT]]/usr/lib"
-// CHECK-LD-64-STATIC: "--start-group" "-lgcc" "-lgcc_eh" "-lc" "--end-group"
+// CHECK-LD-64-STATIC: "--start-group" "{{[^"]*}}/libclang_rt.bitint{{[^"]*}}" "-lgcc" "-lgcc_eh" "-lc" "--end-group"
// RUN: %clang -no-pie -### %s --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform -shared -static \
// RUN: --gcc-toolchain= --sysroot=%S/Inputs/basic_linux_tree 2>&1 | FileCheck --check-prefix=CHECK-LD-SHARED-STATIC %s
Index: clang/test/CodeGen/ext-int-cc.c
===================================================================
--- clang/test/CodeGen/ext-int-cc.c
+++ clang/test/CodeGen/ext-int-cc.c
@@ -123,33 +123,33 @@
// are negated. This will give an error when a target does support larger
// _BitInt widths to alert us to enable the test.
void ParamPassing4(_BitInt(129) a) {}
-// LIN64-NOT: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
-// WIN64-NOT: define dso_local void @ParamPassing4(i129* %{{.+}})
-// LIN32-NOT: define{{.*}} void @ParamPassing4(i129* %{{.+}})
-// WIN32-NOT: define dso_local void @ParamPassing4(i129* %{{.+}})
-// NACL-NOT: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
-// NVPTX64-NOT: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
-// NVPTX-NOT: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
-// SPARCV9-NOT: define{{.*}} void @ParamPassing4(i129* %{{.+}})
-// SPARC-NOT: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
-// MIPS64-NOT: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
-// MIPS-NOT: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
-// SPIR64-NOT: define{{.*}} spir_func void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
-// SPIR-NOT: define{{.*}} spir_func void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
-// HEX-NOT: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
-// LANAI-NOT: define{{.*}} void @ParamPassing4(i129* byval(i129) align 4 %{{.+}})
-// R600-NOT: define{{.*}} void @ParamPassing4(i129 addrspace(5)* byval(i129) align 8 %{{.+}})
-// ARC-NOT: define{{.*}} void @ParamPassing4(i129* byval(i129) align 4 %{{.+}})
-// XCORE-NOT: define{{.*}} void @ParamPassing4(i129* byval(i129) align 4 %{{.+}})
-// RISCV64-NOT: define{{.*}} void @ParamPassing4(i129* %{{.+}})
-// RISCV32-NOT: define{{.*}} void @ParamPassing4(i129* %{{.+}})
-// WASM-NOT: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
-// SYSTEMZ-NOT: define{{.*}} void @ParamPassing4(i129* %{{.+}})
-// PPC64-NOT: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
-// PPC32-NOT: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
-// AARCH64-NOT: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
-// AARCH64DARWIN-NOT: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
-// ARM-NOT: define{{.*}} arm_aapcscc void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
+// LIN64: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
+// WIN64: define dso_local void @ParamPassing4(i129* %{{.+}})
+// LIN32: define{{.*}} void @ParamPassing4(i129* %{{.+}})
+// WIN32: define dso_local void @ParamPassing4(i129* %{{.+}})
+// NACL: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
+// NVPTX64: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
+// NVPTX: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
+// SPARCV9: define{{.*}} void @ParamPassing4(i129* %{{.+}})
+// SPARC: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
+// MIPS64: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
+// MIPS: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
+// SPIR64: define{{.*}} spir_func void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
+// SPIR: define{{.*}} spir_func void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
+// HEX: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
+// LANAI: define{{.*}} void @ParamPassing4(i129* byval(i129) align 4 %{{.+}})
+// R600: define{{.*}} void @ParamPassing4(i129 addrspace(5)* byval(i129) align 8 %{{.+}})
+// ARC: define{{.*}} void @ParamPassing4(i129* byval(i129) align 4 %{{.+}})
+// XCORE: define{{.*}} void @ParamPassing4(i129* byval(i129) align 4 %{{.+}})
+// RISCV64: define{{.*}} void @ParamPassing4(i129* %{{.+}})
+// RISCV32: define{{.*}} void @ParamPassing4(i129* %{{.+}})
+// WASM: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
+// SYSTEMZ: define{{.*}} void @ParamPassing4(i129* %{{.+}})
+// PPC64: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
+// PPC32: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
+// AARCH64: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
+// AARCH64DARWIN: define{{.*}} void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
+// ARM: define{{.*}} arm_aapcscc void @ParamPassing4(i129* byval(i129) align 8 %{{.+}})
#endif
_BitInt(63) ReturnPassing(void){}
@@ -272,38 +272,38 @@
#if __BITINT_MAXWIDTH__ > 128
_BitInt(129) ReturnPassing5(void){}
-// LIN64-NOT: define{{.*}} void @ReturnPassing5(i129* noalias sret
-// WIN64-NOT: define dso_local void @ReturnPassing5(i129* noalias sret
-// LIN32-NOT: define{{.*}} void @ReturnPassing5(i129* noalias sret
-// WIN32-NOT: define dso_local void @ReturnPassing5(i129* noalias sret
-// NACL-NOT: define{{.*}} void @ReturnPassing5(i129* noalias sret
-// NVPTX64-NOT: define{{.*}} i129 @ReturnPassing5(
-// NVPTX-NOT: define{{.*}} i129 @ReturnPassing5(
-// SPARCV9-NOT: define{{.*}} i129 @ReturnPassing5(
-// SPARC-NOT: define{{.*}} void @ReturnPassing5(i129* noalias sret
-// MIPS64-NOT: define{{.*}} void @ReturnPassing5(i129* noalias sret
-// MIPS-NOT: define{{.*}} void @ReturnPassing5(i129* noalias sret
-// SPIR64-NOT: define{{.*}} spir_func void @ReturnPassing5(i129* noalias sret
-// SPIR-NOT: define{{.*}} spir_func void @ReturnPassing5(i129* noalias sret
-// HEX-NOT: define{{.*}} void @ReturnPassing5(i129* noalias sret
-// LANAI-NOT: define{{.*}} void @ReturnPassing5(i129* noalias sret
-// R600-NOT: define{{.*}} void @ReturnPassing5(i129 addrspace(5)* noalias sret
-// ARC-NOT: define{{.*}} void @ReturnPassing5(i129* inreg noalias sret
-// XCORE-NOT: define{{.*}} void @ReturnPassing5(i129* noalias sret
-// RISCV64-NOT: define{{.*}} void @ReturnPassing5(i129* noalias sret
-// RISCV32-NOT: define{{.*}} void @ReturnPassing5(i129* noalias sret
-// WASM-NOT: define{{.*}} void @ReturnPassing5(i129* noalias sret
-// SYSTEMZ-NOT: define{{.*}} void @ReturnPassing5(i129* noalias sret
-// PPC64-NOT: define{{.*}} void @ReturnPassing5(i129* noalias sret
-// PPC32-NOT: define{{.*}} void @ReturnPassing5(i129* noalias sret
-// AARCH64-NOT: define{{.*}} void @ReturnPassing5(i129* noalias sret
-// AARCH64DARWIN-NOT: define{{.*}} void @ReturnPassing5(i129* noalias sret
-// ARM-NOT: define{{.*}} arm_aapcscc void @ReturnPassing5(i129* noalias sret
+// LIN64: define{{.*}} void @ReturnPassing5(i129* noalias sret
+// WIN64: define dso_local void @ReturnPassing5(i129* noalias sret
+// LIN32: define{{.*}} void @ReturnPassing5(i129* noalias sret
+// WIN32: define dso_local void @ReturnPassing5(i129* noalias sret
+// NACL: define{{.*}} void @ReturnPassing5(i129* noalias sret
+// NVPTX64: define{{.*}} i129 @ReturnPassing5(
+// NVPTX: define{{.*}} i129 @ReturnPassing5(
+// SPARCV9: define{{.*}} i129 @ReturnPassing5(
+// SPARC: define{{.*}} void @ReturnPassing5(i129* noalias sret
+// MIPS64: define{{.*}} void @ReturnPassing5(i129* noalias sret
+// MIPS: define{{.*}} void @ReturnPassing5(i129* noalias sret
+// SPIR64: define{{.*}} spir_func void @ReturnPassing5(i129* noalias sret
+// SPIR: define{{.*}} spir_func void @ReturnPassing5(i129* noalias sret
+// HEX: define{{.*}} void @ReturnPassing5(i129* noalias sret
+// LANAI: define{{.*}} void @ReturnPassing5(i129* noalias sret
+// R600: define{{.*}} void @ReturnPassing5(i129 addrspace(5)* noalias sret
+// ARC: define{{.*}} void @ReturnPassing5(i129* inreg noalias sret
+// XCORE: define{{.*}} void @ReturnPassing5(i129* noalias sret
+// RISCV64: define{{.*}} void @ReturnPassing5(i129* noalias sret
+// RISCV32: define{{.*}} void @ReturnPassing5(i129* noalias sret
+// WASM: define{{.*}} void @ReturnPassing5(i129* noalias sret
+// SYSTEMZ: define{{.*}} void @ReturnPassing5(i129* noalias sret
+// PPC64: define{{.*}} void @ReturnPassing5(i129* noalias sret
+// PPC32: define{{.*}} void @ReturnPassing5(i129* noalias sret
+// AARCH64: define{{.*}} void @ReturnPassing5(i129* noalias sret
+// AARCH64DARWIN: define{{.*}} void @ReturnPassing5(i129* noalias sret
+// ARM: define{{.*}} arm_aapcscc void @ReturnPassing5(i129* noalias sret
// SparcV9 is odd in that it has a return-size limit of 256, not 128 or 64
// like other platforms, so test to make sure this behavior will still work.
_BitInt(256) ReturnPassing6(void) {}
-// SPARCV9-NOT: define{{.*}} i256 @ReturnPassing6(
+// SPARCV9: define{{.*}} i256 @ReturnPassing6(
_BitInt(257) ReturnPassing7(void) {}
-// SPARCV9-NOT: define{{.*}} void @ReturnPassing7(i257* noalias sret
+// SPARCV9: define{{.*}} void @ReturnPassing7(i257* noalias sret
#endif
Index: clang/lib/Sema/SemaCast.cpp
===================================================================
--- clang/lib/Sema/SemaCast.cpp
+++ clang/lib/Sema/SemaCast.cpp
@@ -3136,6 +3136,9 @@
if (SrcExpr.isInvalid())
return;
+ Self.diagnoseBitIntToFloating(Kind, SrcExpr.get());
+ Self.diagnoseFloatingToBitInt(Kind, DestType, SrcExpr.get());
+
if (Kind == CK_BitCast)
checkCastAlign();
}
Index: clang/lib/Sema/Sema.cpp
===================================================================
--- clang/lib/Sema/Sema.cpp
+++ clang/lib/Sema/Sema.cpp
@@ -625,6 +625,25 @@
<< FixItHint::CreateReplacement(E->getSourceRange(), "nullptr");
}
+void Sema::diagnoseBitIntToFloating(CastKind Kind, const Expr *E) {
+ if (Kind != CK_IntegralToFloating)
+ return;
+
+ auto Ty = E->getType();
+ if (Ty->isBitIntType() && getASTContext().getIntWidth(Ty) > 128) {
+ Diag(E->getBeginLoc(), diag::err_int_to_float_bit_int_max_size) << 128;
+ }
+}
+
+void Sema::diagnoseFloatingToBitInt(CastKind Kind, QualType Ty, const Expr *E) {
+ if (Kind != CK_FloatingToIntegral)
+ return;
+
+ if (Ty->isBitIntType() && getASTContext().getIntWidth(Ty) > 128) {
+ Diag(E->getBeginLoc(), diag::err_float_to_int_bit_int_max_size) << 128;
+ }
+}
+
/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
/// If there is already an implicit cast, merge into the existing one.
/// The result is of the given category.
@@ -656,6 +675,8 @@
diagnoseNullableToNonnullConversion(Ty, E->getType(), E->getBeginLoc());
diagnoseZeroToNullptrConversion(Kind, E);
+ diagnoseBitIntToFloating(Kind, E);
+ diagnoseFloatingToBitInt(Kind, Ty, E);
QualType ExprTy = Context.getCanonicalType(E->getType());
QualType TypeTy = Context.getCanonicalType(Ty);
Index: clang/lib/Lex/LiteralSupport.cpp
===================================================================
--- clang/lib/Lex/LiteralSupport.cpp
+++ clang/lib/Lex/LiteralSupport.cpp
@@ -1227,9 +1227,32 @@
return Val.getZExtValue() != N;
}
- Val = 0;
const char *Ptr = DigitsBegin;
+ if (llvm::isPowerOf2_32(radix)) {
+ unsigned BitsPerDigit = llvm::Log2(radix);
+ unsigned BitPos = NumDigits * BitsPerDigit;
+
+ llvm::APInt Temp(BitPos, 0);
+
+ while (Ptr < SuffixBegin) {
+ if (isDigitSeparator(*Ptr)) {
+ ++Ptr;
+ continue;
+ }
+ unsigned C = llvm::hexDigitValue(*Ptr++);
+ BitPos -= BitsPerDigit;
+ Temp.insertBits(C, BitPos, BitsPerDigit);
+ }
+
+ // Due to digit separators, BitPos might be greater than zero.
+ Temp.lshrInPlace(BitPos);
+
+ Val = Temp.zextOrTrunc(Val.getBitWidth());
+ return Temp.getActiveBits() > Val.getBitWidth();
+ }
+
+ Val = 0;
llvm::APInt RadixVal(Val.getBitWidth(), radix);
llvm::APInt CharVal(Val.getBitWidth(), 0);
llvm::APInt OldVal = Val;
Index: clang/lib/Driver/ToolChains/MinGW.cpp
===================================================================
--- clang/lib/Driver/ToolChains/MinGW.cpp
+++ clang/lib/Driver/ToolChains/MinGW.cpp
@@ -64,6 +64,8 @@
CmdArgs.push_back("-lmingwthrd");
CmdArgs.push_back("-lmingw32");
+ addBitIntRuntime(getToolChain(), CmdArgs, Args);
+
// Make use of compiler-rt if --rtlib option is used
ToolChain::RuntimeLibType RLT = getToolChain().GetRuntimeLibType(Args);
if (RLT == ToolChain::RLT_Libgcc) {
Index: clang/lib/Driver/ToolChains/Gnu.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Gnu.cpp
+++ clang/lib/Driver/ToolChains/Gnu.cpp
@@ -610,6 +610,8 @@
// FIXME: Does this really make sense for all GNU toolchains?
WantPthread = true;
+ addBitIntRuntime(getToolChain(), CmdArgs, Args);
+
AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
if (WantPthread && !isAndroid)
Index: clang/lib/Driver/ToolChains/CommonArgs.h
===================================================================
--- clang/lib/Driver/ToolChains/CommonArgs.h
+++ clang/lib/Driver/ToolChains/CommonArgs.h
@@ -45,6 +45,9 @@
void linkXRayRuntimeDeps(const ToolChain &TC,
llvm::opt::ArgStringList &CmdArgs);
+void addBitIntRuntime(const ToolChain &TC, llvm::opt::ArgStringList &CmdArgs,
+ const llvm::opt::ArgList &Args);
+
void AddRunTimeLibs(const ToolChain &TC, const Driver &D,
llvm::opt::ArgStringList &CmdArgs,
const llvm::opt::ArgList &Args);
Index: clang/lib/Driver/ToolChains/CommonArgs.cpp
===================================================================
--- clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -987,6 +987,16 @@
return !StaticRuntimes.empty() || !NonWholeStaticRuntimes.empty();
}
+void tools::addBitIntRuntime(const ToolChain &TC, ArgStringList &CmdArgs,
+ const ArgList &Args) {
+ std::string BitIntPath = TC.getCompilerRT(Args, "bitint");
+
+ // While building compiler-rt itself, this library is not available,
+ // so we don't try to link it.
+ if (TC.getVFS().exists(BitIntPath))
+ CmdArgs.push_back(Args.MakeArgString(BitIntPath));
+}
+
bool tools::addXRayRuntime(const ToolChain&TC, const ArgList &Args, ArgStringList &CmdArgs) {
if (Args.hasArg(options::OPT_shared))
return false;
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -5027,6 +5027,10 @@
/// Warn when implicitly casting 0 to nullptr.
void diagnoseZeroToNullptrConversion(CastKind Kind, const Expr *E);
+ /// Error out when casting a floating point value to a large _BitInt
+ void diagnoseBitIntToFloating(CastKind Kind, const Expr *E);
+ void diagnoseFloatingToBitInt(CastKind Kind, QualType Ty, const Expr *E);
+
ParsingDeclState PushParsingDeclaration(sema::DelayedDiagnosticPool &pool) {
return DelayedDiagnostics.push(pool);
}
Index: clang/include/clang/Basic/TargetInfo.h
===================================================================
--- clang/include/clang/Basic/TargetInfo.h
+++ clang/include/clang/Basic/TargetInfo.h
@@ -31,6 +31,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Frontend/OpenMP/OMPGridValues.h"
+#include "llvm/IR/DerivedTypes.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/VersionTuple.h"
@@ -595,12 +596,8 @@
// Different targets may support a different maximum width for the _BitInt
// type, depending on what operations are supported.
virtual size_t getMaxBitIntWidth() const {
- // FIXME: this value should be llvm::IntegerType::MAX_INT_BITS, which is
- // maximum bit width that LLVM claims its IR can support. However, most
- // backends currently have a bug where they only support division
- // operations on types that are <= 128 bits and crash otherwise. We're
- // setting the max supported value to 128 to be conservative.
- return 128;
+ // TODO: Return 128 for targets that don't link libbitint?
+ return llvm::IntegerType::MAX_INT_BITS;
}
/// Determine whether _Float16 is supported on this target.
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8419,6 +8419,12 @@
"__builtin_mul_overflow does not support 'signed _BitInt' operands of more "
"than %0 bits">;
+def err_int_to_float_bit_int_max_size : Error<
+ "cannot convert '_BitInt' operands of more than %0 bits to floating point">;
+
+def err_float_to_int_bit_int_max_size : Error<
+ "cannot convert floating point operands to a '_BitInt' of more than %0 bits">;
+
def err_atomic_load_store_uses_lib : Error<
"atomic %select{load|store}0 requires runtime support that is not "
"available for this target">;
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits