Skip to content

Commit 2fd180b

Browse files
committed
[IR] Reduce max supported integer from 2^24-1 to 2^23.
SelectionDAG will promote illegal types up to a power of 2 before splitting down to a legal type. This will create an IntegerType with a bit width that must be <= MAX_INT_BITS. This places an effective upper limit on any type of 2^23 so that we don't try create a 2^24 type. I considered putting a fatal error somewhere in the path from TargetLowering::getTypeConversion down to IntegerType::get, but limiting the type in IR seemed better. This breaks backwards compatibility with IR that is using a really large type. I suspect such IR is going to be very rare due to the the compile time costs such a type likely incurs. Prevents the ICE in PR51829. Reviewed By: efriedma, aaron.ballman Differential Revision: https://reviews.llvm.org/D109721
1 parent 6ee55f9 commit 2fd180b

File tree

9 files changed

+29
-26
lines changed

9 files changed

+29
-26
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ Improvements to Clang's diagnostics
5656
Non-comprehensive list of changes in this release
5757
-------------------------------------------------
5858

59-
- ...
59+
- Maximum _ExtInt size was decreased from 16,777,215 bits to 8,388,608 bits.
60+
Motivation for this was discussed in PR51829.
6061

6162
New Compiler Flags
6263
------------------

clang/test/CodeGen/ext-int.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ void VLATest(_ExtInt(3) A, _ExtInt(99) B, _ExtInt(123456) C) {
2828

2929
struct S {
3030
_ExtInt(17) A;
31-
_ExtInt(16777200) B;
31+
_ExtInt(8388600) B;
3232
_ExtInt(17) C;
3333
};
3434

@@ -41,9 +41,9 @@ void OffsetOfTest() {
4141
// LIN32: store i32 4, i32* %{{.+}}
4242
// WINCHECK32: store i32 8, i32* %{{.+}}
4343
int C = __builtin_offsetof(struct S,C);
44-
// CHECK64: store i32 2097160, i32* %{{.+}}
45-
// LIN32: store i32 2097156, i32* %{{.+}}
46-
// WIN32: store i32 2097160, i32* %{{.+}}
44+
// CHECK64: store i32 1048584, i32* %{{.+}}
45+
// LIN32: store i32 1048580, i32* %{{.+}}
46+
// WIN32: store i32 1048584, i32* %{{.+}}
4747
}
4848

4949
void Size1ExtIntParam(unsigned _ExtInt(1) A) {

clang/test/CodeGenCXX/ext-int.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -223,23 +223,23 @@ void TakesVarargs(int i, ...) {
223223
// WIN: %[[LOADV4:.+]] = load i129, i129* %[[LOADP4]]
224224
// WIN: store i129 %[[LOADV4]], i129*
225225

226-
_ExtInt(16777200) E = __builtin_va_arg(args, _ExtInt(16777200));
226+
_ExtInt(8388600) E = __builtin_va_arg(args, _ExtInt(8388600));
227227
// LIN: %[[AD5:.+]] = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %[[ARGS]]
228228
// LIN: %[[OFA_P5:.+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* %[[AD5]], i32 0, i32 2
229229
// LIN: %[[OFA5:.+]] = load i8*, i8** %[[OFA_P5]]
230-
// LIN: %[[BC5:.+]] = bitcast i8* %[[OFA5]] to i16777200*
231-
// LIN: %[[OFANEXT5:.+]] = getelementptr i8, i8* %[[OFA5]], i32 2097152
230+
// LIN: %[[BC5:.+]] = bitcast i8* %[[OFA5]] to i8388600*
231+
// LIN: %[[OFANEXT5:.+]] = getelementptr i8, i8* %[[OFA5]], i32 1048576
232232
// LIN: store i8* %[[OFANEXT5]], i8** %[[OFA_P5]]
233-
// LIN: %[[LOAD5:.+]] = load i16777200, i16777200* %[[BC5]]
234-
// LIN: store i16777200 %[[LOAD5]], i16777200*
233+
// LIN: %[[LOAD5:.+]] = load i8388600, i8388600* %[[BC5]]
234+
// LIN: store i8388600 %[[LOAD5]], i8388600*
235235

236236
// WIN: %[[CUR5:.+]] = load i8*, i8** %[[ARGS]]
237237
// WIN: %[[NEXT5:.+]] = getelementptr inbounds i8, i8* %[[CUR5]], i64 8
238238
// WIN: store i8* %[[NEXT5]], i8** %[[ARGS]]
239-
// WIN: %[[BC5:.+]] = bitcast i8* %[[CUR5]] to i16777200**
240-
// WIN: %[[LOADP5:.+]] = load i16777200*, i16777200** %[[BC5]]
241-
// WIN: %[[LOADV5:.+]] = load i16777200, i16777200* %[[LOADP5]]
242-
// WIN: store i16777200 %[[LOADV5]], i16777200*
239+
// WIN: %[[BC5:.+]] = bitcast i8* %[[CUR5]] to i8388600**
240+
// WIN: %[[LOADP5:.+]] = load i8388600*, i8388600** %[[BC5]]
241+
// WIN: %[[LOADV5:.+]] = load i8388600, i8388600* %[[LOADP5]]
242+
// WIN: store i8388600 %[[LOADV5]], i8388600*
243243

244244
__builtin_va_end(args);
245245
// LIN: %[[ENDAD:.+]] = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %[[ARGS]]
@@ -295,7 +295,7 @@ void ExplicitCasts() {
295295

296296
struct S {
297297
_ExtInt(17) A;
298-
_ExtInt(16777200) B;
298+
_ExtInt(8388600) B;
299299
_ExtInt(17) C;
300300
};
301301

@@ -308,7 +308,7 @@ void OffsetOfTest() {
308308
auto B = __builtin_offsetof(S,B);
309309
// CHECK: store i64 8, i64* %{{.+}}
310310
auto C = __builtin_offsetof(S,C);
311-
// CHECK: store i64 2097160, i64* %{{.+}}
311+
// CHECK: store i64 1048584, i64* %{{.+}}
312312
}
313313

314314

clang/test/SemaCXX/ext-int.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ _ExtInt(33) Declarations(_ExtInt(48) &Param) { // Useable in params and returns.
2929
constexpr _ExtInt(7) o = 33;
3030

3131
// Check LLVM imposed max size.
32-
_ExtInt(0xFFFFFFFFFF) p; // expected-error {{signed _ExtInt of bit sizes greater than 16777215 not supported}}
33-
unsigned _ExtInt(0xFFFFFFFFFF) q; // expected-error {{unsigned _ExtInt of bit sizes greater than 16777215 not supported}}
32+
_ExtInt(8388609) p; // expected-error {{signed _ExtInt of bit sizes greater than 8388608 not supported}}
33+
unsigned _ExtInt(0xFFFFFFFFFF) q; // expected-error {{unsigned _ExtInt of bit sizes greater than 8388608 not supported}}
3434

3535
// Ensure template params are instantiated correctly.
3636
// expected-error@5{{signed _ExtInt must have a bit size of at least 2}}

llvm/docs/LangRef.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3303,7 +3303,7 @@ Integer Type
33033303

33043304
The integer type is a very simple type that simply specifies an
33053305
arbitrary bit width for the integer type desired. Any bit width from 1
3306-
bit to 2\ :sup:`23`\ -1 (about 8 million) can be specified.
3306+
bit to 2\ :sup:`23`\ (about 8 million) can be specified.
33073307

33083308
:Syntax:
33093309

llvm/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ Changes to the LLVM IR
5959
* Using the legacy pass manager for the optimization pipeline is deprecated and
6060
will be removed after LLVM 14. In the meantime, only minimal effort will be
6161
made to maintain the legacy pass manager for the optimization pipeline.
62+
* Max allowed integer type was reduced from 2^24-1 bits to 2^23 bits.
6263

6364
Changes to building LLVM
6465
------------------------

llvm/include/llvm/IR/DerivedTypes.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,11 @@ class IntegerType : public Type {
4949
/// This enum is just used to hold constants we need for IntegerType.
5050
enum {
5151
MIN_INT_BITS = 1, ///< Minimum number of bits that can be specified
52-
MAX_INT_BITS = (1<<24)-1 ///< Maximum number of bits that can be specified
52+
MAX_INT_BITS = (1<<23) ///< Maximum number of bits that can be specified
5353
///< Note that bit width is stored in the Type classes SubclassData field
54-
///< which has 24 bits. This yields a maximum bit width of 16,777,215
55-
///< bits.
54+
///< which has 24 bits. SelectionDAG type legalization can require a
55+
///< power of 2 IntegerType, so limit to the largest representable power
56+
///< of 2, 8388608.
5657
};
5758

5859
/// This static method is the primary way of constructing an IntegerType.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; RUN: not llvm-as < %s 2>&1 | FileCheck %s
22

3-
; i16777216 is the smallest integer type that can't be represented in LLVM IR
4-
@i2 = common global i16777216 0, align 4
3+
; i8388609 is the smallest integer type that can't be represented in LLVM IR
4+
@i2 = common global i8388609 0, align 4
55
; CHECK: expected type

llvm/test/Assembler/max-inttype.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
; RUN: llvm-as < %s | llvm-dis
22

3-
; i16777215 is the maximum integer type represented in LLVM IR
4-
@i2 = common global i16777215 0, align 4
3+
; i838608 is the maximum integer type represented in LLVM IR
4+
@i2 = common global i838608 0, align 4

0 commit comments

Comments
 (0)