Skip to content

Commit

Permalink
[IR] Reduce max supported integer from 2^24-1 to 2^23.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
topperc committed Sep 14, 2021
1 parent 6ee55f9 commit 2fd180b
Show file tree
Hide file tree
Showing 9 changed files with 29 additions and 26 deletions.
3 changes: 2 additions & 1 deletion clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ Improvements to Clang's diagnostics
Non-comprehensive list of changes in this release
-------------------------------------------------

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

New Compiler Flags
------------------
Expand Down
8 changes: 4 additions & 4 deletions clang/test/CodeGen/ext-int.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ void VLATest(_ExtInt(3) A, _ExtInt(99) B, _ExtInt(123456) C) {

struct S {
_ExtInt(17) A;
_ExtInt(16777200) B;
_ExtInt(8388600) B;
_ExtInt(17) C;
};

Expand All @@ -41,9 +41,9 @@ void OffsetOfTest() {
// LIN32: store i32 4, i32* %{{.+}}
// WINCHECK32: store i32 8, i32* %{{.+}}
int C = __builtin_offsetof(struct S,C);
// CHECK64: store i32 2097160, i32* %{{.+}}
// LIN32: store i32 2097156, i32* %{{.+}}
// WIN32: store i32 2097160, i32* %{{.+}}
// CHECK64: store i32 1048584, i32* %{{.+}}
// LIN32: store i32 1048580, i32* %{{.+}}
// WIN32: store i32 1048584, i32* %{{.+}}
}

void Size1ExtIntParam(unsigned _ExtInt(1) A) {
Expand Down
22 changes: 11 additions & 11 deletions clang/test/CodeGenCXX/ext-int.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,23 +223,23 @@ void TakesVarargs(int i, ...) {
// WIN: %[[LOADV4:.+]] = load i129, i129* %[[LOADP4]]
// WIN: store i129 %[[LOADV4]], i129*

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

// WIN: %[[CUR5:.+]] = load i8*, i8** %[[ARGS]]
// WIN: %[[NEXT5:.+]] = getelementptr inbounds i8, i8* %[[CUR5]], i64 8
// WIN: store i8* %[[NEXT5]], i8** %[[ARGS]]
// WIN: %[[BC5:.+]] = bitcast i8* %[[CUR5]] to i16777200**
// WIN: %[[LOADP5:.+]] = load i16777200*, i16777200** %[[BC5]]
// WIN: %[[LOADV5:.+]] = load i16777200, i16777200* %[[LOADP5]]
// WIN: store i16777200 %[[LOADV5]], i16777200*
// WIN: %[[BC5:.+]] = bitcast i8* %[[CUR5]] to i8388600**
// WIN: %[[LOADP5:.+]] = load i8388600*, i8388600** %[[BC5]]
// WIN: %[[LOADV5:.+]] = load i8388600, i8388600* %[[LOADP5]]
// WIN: store i8388600 %[[LOADV5]], i8388600*

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

struct S {
_ExtInt(17) A;
_ExtInt(16777200) B;
_ExtInt(8388600) B;
_ExtInt(17) C;
};

Expand All @@ -308,7 +308,7 @@ void OffsetOfTest() {
auto B = __builtin_offsetof(S,B);
// CHECK: store i64 8, i64* %{{.+}}
auto C = __builtin_offsetof(S,C);
// CHECK: store i64 2097160, i64* %{{.+}}
// CHECK: store i64 1048584, i64* %{{.+}}
}


Expand Down
4 changes: 2 additions & 2 deletions clang/test/SemaCXX/ext-int.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ _ExtInt(33) Declarations(_ExtInt(48) &Param) { // Useable in params and returns.
constexpr _ExtInt(7) o = 33;

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

// Ensure template params are instantiated correctly.
// expected-error@5{{signed _ExtInt must have a bit size of at least 2}}
Expand Down
2 changes: 1 addition & 1 deletion llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3303,7 +3303,7 @@ Integer Type

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

:Syntax:

Expand Down
1 change: 1 addition & 0 deletions llvm/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ Changes to the LLVM IR
* Using the legacy pass manager for the optimization pipeline is deprecated and
will be removed after LLVM 14. In the meantime, only minimal effort will be
made to maintain the legacy pass manager for the optimization pipeline.
* Max allowed integer type was reduced from 2^24-1 bits to 2^23 bits.

Changes to building LLVM
------------------------
Expand Down
7 changes: 4 additions & 3 deletions llvm/include/llvm/IR/DerivedTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,11 @@ class IntegerType : public Type {
/// This enum is just used to hold constants we need for IntegerType.
enum {
MIN_INT_BITS = 1, ///< Minimum number of bits that can be specified
MAX_INT_BITS = (1<<24)-1 ///< Maximum number of bits that can be specified
MAX_INT_BITS = (1<<23) ///< Maximum number of bits that can be specified
///< Note that bit width is stored in the Type classes SubclassData field
///< which has 24 bits. This yields a maximum bit width of 16,777,215
///< bits.
///< which has 24 bits. SelectionDAG type legalization can require a
///< power of 2 IntegerType, so limit to the largest representable power
///< of 2, 8388608.
};

/// This static method is the primary way of constructing an IntegerType.
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/Assembler/invalid-inttype.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
; RUN: not llvm-as < %s 2>&1 | FileCheck %s

; i16777216 is the smallest integer type that can't be represented in LLVM IR
@i2 = common global i16777216 0, align 4
; i8388609 is the smallest integer type that can't be represented in LLVM IR
@i2 = common global i8388609 0, align 4
; CHECK: expected type
4 changes: 2 additions & 2 deletions llvm/test/Assembler/max-inttype.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: llvm-as < %s | llvm-dis

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

0 comments on commit 2fd180b

Please sign in to comment.