Skip to content

Commit 564d85e

Browse files
committed
The maximal representable alignment in LLVM IR is 1GiB, not 512MiB
In LLVM IR, `AlignmentBitfieldElementT` is 5-bit wide But that means that the maximal alignment exponent is `(1<<5)-2`, which is `30`, not `29`. And indeed, alignment of `1073741824` roundtrips IR serialization-deserialization. While this doesn't seem all that important, this doubles the maximal supported alignment from 512MiB to 1GiB, and there's actually one noticeable use-case for that; On X86, the huge pages can have sizes of 2MiB and 1GiB (!). So while this doesn't add support for truly huge alignments, which i think we can easily-ish do if wanted, i think this adds zero-cost support for a not-trivially-dismissable case. I don't believe we need any upgrade infrastructure, and since we don't explicitly record the IR version, we don't need to bump one either. As @craig.topper speculates in D108661#2963519, this might be an artificial limit imposed by the original implementation of the `getAlignment()` functions. Differential Revision: https://reviews.llvm.org/D108661
1 parent 5ece556 commit 564d85e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+184
-138
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ class Sema final {
396396
///
397397
/// This is the greatest alignment value supported by load, store, and alloca
398398
/// instructions, and global values.
399-
static const unsigned MaxAlignmentExponent = 29;
399+
static const unsigned MaxAlignmentExponent = 30;
400400
static const unsigned MaximumAlignment = 1u << MaxAlignmentExponent;
401401

402402
typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;

clang/test/CXX/drs/dr6xx.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -551,9 +551,11 @@ namespace dr648 { // dr648: yes
551551

552552
#if __cplusplus >= 201103L
553553
namespace dr649 { // dr649: yes
554-
alignas(0x40000000) int n; // expected-error {{requested alignment}}1
555-
struct alignas(0x40000000) X {}; // expected-error {{requested alignment}}
556-
struct Y { int n alignas(0x40000000); }; // expected-error {{requested alignment}}
554+
alignas(0x80000000) int n; // expected-error {{requested alignment}}1
555+
struct alignas(0x80000000) X {}; // expected-error {{requested alignment}}
556+
struct Y {
557+
int n alignas(0x80000000); // expected-error {{requested alignment}}
558+
};
557559
struct alignas(256) Z {};
558560
// This part is superseded by dr2130 and eventually by aligned allocation support.
559561
auto *p = new Z;

clang/test/CodeGen/builtin-assume-aligned.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ int test6() {
117117
// CHECK-NEXT: store i32* [[A]], i32** [[A_ADDR]], align 8
118118
// CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[A_ADDR]], align 8
119119
// CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[TMP0]] to i8*
120-
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* [[TMP1]], i64 536870912) ]
120+
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* [[TMP1]], i64 1073741824) ]
121121
// CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
122122
// CHECK-NEXT: store i32* [[TMP2]], i32** [[A_ADDR]], align 8
123123
// CHECK-NEXT: [[TMP3:%.*]] = load i32*, i32** [[A_ADDR]], align 8

clang/test/CodeGen/catch-alignment-assumption-attribute-align_value-on-paramvar.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// CHECK-SANITIZE-ANYRECOVER: @[[LINE_100_ALIGNMENT_ASSUMPTION:.*]] = {{.*}}, i32 100, i32 10 }, {{.*}}* @[[CHAR]] }
88

99
char **passthrough(__attribute__((align_value(0x80000000))) char **x) {
10-
// CHECK-NOSANITIZE: define{{.*}} i8** @{{.*}}(i8** align 536870912 %[[X:.*]])
10+
// CHECK-NOSANITIZE: define{{.*}} i8** @{{.*}}(i8** align 1073741824 %[[X:.*]])
1111
// CHECK-SANITIZE: define{{.*}} i8** @{{.*}}(i8** %[[X:.*]])
1212
// CHECK-NEXT: [[entry:.*]]:
1313
// CHECK-NEXT: %[[X_ADDR:.*]] = alloca i8**, align 8

clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params-variable.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,17 @@ void *caller(char **x, unsigned long offset) {
1818
// CHECK-NEXT: %[[OFFSET_RELOADED:.*]] = load i64, i64* %[[OFFSET_ADDR]], align 8
1919
// CHECK-SANITIZE-NEXT: %[[PTRINT:.*]] = ptrtoint i8* %[[BITCAST]] to i64
2020
// CHECK-SANITIZE-NEXT: %[[OFFSETPTR:.*]] = sub i64 %[[PTRINT]], %[[OFFSET_RELOADED]]
21-
// CHECK-SANITIZE-NEXT: %[[MASKEDPTR:.*]] = and i64 %[[OFFSETPTR]], 536870911
21+
// CHECK-SANITIZE-NEXT: %[[MASKEDPTR:.*]] = and i64 %[[OFFSETPTR]], 1073741823
2222
// CHECK-SANITIZE-NEXT: %[[MASKCOND:.*]] = icmp eq i64 %[[MASKEDPTR]], 0
2323
// CHECK-SANITIZE-NEXT: %[[PTRINT_DUP:.*]] = ptrtoint i8* %[[BITCAST]] to i64, !nosanitize
2424
// CHECK-SANITIZE-NEXT: br i1 %[[MASKCOND]], label %[[CONT:.*]], label %[[HANDLER_ALIGNMENT_ASSUMPTION:[^,]+]],{{.*}} !nosanitize
2525
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
26-
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 536870912, i64 %[[OFFSET_RELOADED]]){{.*}}, !nosanitize
27-
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 536870912, i64 %[[OFFSET_RELOADED]]){{.*}}, !nosanitize
26+
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 1073741824, i64 %[[OFFSET_RELOADED]]){{.*}}, !nosanitize
27+
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 1073741824, i64 %[[OFFSET_RELOADED]]){{.*}}, !nosanitize
2828
// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 23){{.*}}, !nosanitize
2929
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
3030
// CHECK-SANITIZE: [[CONT]]:
31-
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* %[[BITCAST]], i64 536870912, i64 %[[OFFSET_RELOADED]]) ]
31+
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* %[[BITCAST]], i64 1073741824, i64 %[[OFFSET_RELOADED]]) ]
3232
// CHECK-NEXT: ret i8* %[[BITCAST]]
3333
// CHECK-NEXT: }
3434
#line 100

clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,17 @@ void *caller(char **x) {
1515
// CHECK-NEXT: %[[BITCAST:.*]] = bitcast i8** %[[X_RELOADED]] to i8*
1616
// CHECK-SANITIZE-NEXT: %[[PTRINT:.*]] = ptrtoint i8* %[[BITCAST]] to i64
1717
// CHECK-SANITIZE-NEXT: %[[OFFSETPTR:.*]] = sub i64 %[[PTRINT]], 42
18-
// CHECK-SANITIZE-NEXT: %[[MASKEDPTR:.*]] = and i64 %[[OFFSETPTR]], 536870911
18+
// CHECK-SANITIZE-NEXT: %[[MASKEDPTR:.*]] = and i64 %[[OFFSETPTR]], 1073741823
1919
// CHECK-SANITIZE-NEXT: %[[MASKCOND:.*]] = icmp eq i64 %[[MASKEDPTR]], 0
2020
// CHECK-SANITIZE-NEXT: %[[PTRINT_DUP:.*]] = ptrtoint i8* %[[BITCAST]] to i64, !nosanitize
2121
// CHECK-SANITIZE-NEXT: br i1 %[[MASKCOND]], label %[[CONT:.*]], label %[[HANDLER_ALIGNMENT_ASSUMPTION:[^,]+]],{{.*}} !nosanitize
2222
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
23-
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 536870912, i64 42){{.*}}, !nosanitize
24-
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 536870912, i64 42){{.*}}, !nosanitize
23+
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 1073741824, i64 42){{.*}}, !nosanitize
24+
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 1073741824, i64 42){{.*}}, !nosanitize
2525
// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 23){{.*}}, !nosanitize
2626
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
2727
// CHECK-SANITIZE: [[CONT]]:
28-
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* %[[BITCAST]], i64 536870912, i64 42) ]
28+
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* %[[BITCAST]], i64 1073741824, i64 42) ]
2929
// CHECK-NEXT: ret i8* %[[BITCAST]]
3030
// CHECK-NEXT: }
3131
#line 100

clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-two-params.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@ void *caller(char **x) {
1414
// CHECK-NEXT: %[[X_RELOADED:.*]] = load i8**, i8*** %[[X_ADDR]], align 8
1515
// CHECK-NEXT: %[[BITCAST:.*]] = bitcast i8** %[[X_RELOADED]] to i8*
1616
// CHECK-SANITIZE-NEXT: %[[PTRINT:.*]] = ptrtoint i8* %[[BITCAST]] to i64
17-
// CHECK-SANITIZE-NEXT: %[[MASKEDPTR:.*]] = and i64 %[[PTRINT]], 536870911
17+
// CHECK-SANITIZE-NEXT: %[[MASKEDPTR:.*]] = and i64 %[[PTRINT]], 1073741823
1818
// CHECK-SANITIZE-NEXT: %[[MASKCOND:.*]] = icmp eq i64 %[[MASKEDPTR]], 0
1919
// CHECK-SANITIZE-NEXT: %[[PTRINT_DUP:.*]] = ptrtoint i8* %[[BITCAST]] to i64, !nosanitize
2020
// CHECK-SANITIZE-NEXT: br i1 %[[MASKCOND]], label %[[CONT:.*]], label %[[HANDLER_ALIGNMENT_ASSUMPTION:[^,]+]],{{.*}} !nosanitize
2121
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
22-
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 536870912, i64 0){{.*}}, !nosanitize
23-
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 536870912, i64 0){{.*}}, !nosanitize
22+
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 1073741824, i64 0){{.*}}, !nosanitize
23+
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 1073741824, i64 0){{.*}}, !nosanitize
2424
// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 23){{.*}}, !nosanitize
2525
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
2626
// CHECK-SANITIZE: [[CONT]]:
27-
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* %[[BITCAST]], i64 536870912) ]
27+
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* %[[BITCAST]], i64 1073741824) ]
2828
// CHECK-NEXT: ret i8* %[[BITCAST]]
2929
// CHECK-NEXT: }
3030
#line 100

clang/test/CodeGen/catch-alignment-assumption-openmp.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,20 @@ void func(char *data) {
1313
// CHECK: store i8* %[[DATA]], i8** %[[DATA_ADDR]], align 8
1414
// CHECK: %[[DATA_RELOADED:.*]] = load i8*, i8** %[[DATA_ADDR]], align 8
1515
// CHECK-SANITIZE-NEXT: %[[PTRINT:.*]] = ptrtoint i8* %[[DATA_RELOADED]] to i64
16-
// CHECK-SANITIZE-NEXT: %[[MASKEDPTR:.*]] = and i64 %[[PTRINT]], 1073741823
16+
// CHECK-SANITIZE-NEXT: %[[MASKEDPTR:.*]] = and i64 %[[PTRINT]], 2147483647
1717
// CHECK-SANITIZE-NEXT: %[[MASKCOND:.*]] = icmp eq i64 %[[MASKEDPTR]], 0
1818
// CHECK-SANITIZE-NEXT: %[[PTRINT_DUP:.*]] = ptrtoint i8* %[[DATA_RELOADED]] to i64, !nosanitize
1919
// CHECK-SANITIZE-NEXT: br i1 %[[MASKCOND]], label %[[CONT:.*]], label %[[HANDLER_ALIGNMENT_ASSUMPTION:[^,]+]],{{.*}} !nosanitize
2020
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
21-
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 1073741824, i64 0){{.*}}, !nosanitize
22-
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 1073741824, i64 0){{.*}}, !nosanitize
21+
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 2147483648, i64 0){{.*}}, !nosanitize
22+
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 2147483648, i64 0){{.*}}, !nosanitize
2323
// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 23){{.*}}, !nosanitize
2424
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
2525
// CHECK-SANITIZE: [[CONT]]:
26-
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* %[[DATA_RELOADED]], i64 1073741824) ]
26+
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i8* %[[DATA_RELOADED]], i64 2147483648) ]
2727

2828
#line 100
29-
#pragma omp for simd aligned(data : 0x40000000)
29+
#pragma omp for simd aligned(data : 0x80000000)
3030
for (int x = 0; x < 1; x++)
3131
data[x] = data[x];
3232
}

clang/test/Sema/alloc-align-attr.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
// return values
44
void test_void_alloc_align(void) __attribute__((alloc_align(1))); // expected-warning {{'alloc_align' attribute only applies to return values that are pointers}}
5-
void *test_ptr_alloc_align(int a) __attribute__((alloc_align(1))); // no-warning
5+
void *test_ptr_alloc_align(unsigned int a) __attribute__((alloc_align(1))); // no-warning
66

77
int j __attribute__((alloc_align(1))); // expected-warning {{'alloc_align' attribute only applies to non-K&R-style functions}}
88
void *test_no_params_zero(void) __attribute__((alloc_align(0))); // expected-error {{'alloc_align' attribute parameter 1 is out of bounds}}
@@ -26,6 +26,6 @@ void *align16() {
2626
void *align15() {
2727
return test_ptr_alloc_align(15); // expected-warning {{requested alignment is not a power of 2}}
2828
}
29-
void *align536870912() {
30-
return test_ptr_alloc_align(1073741824); // expected-warning {{requested alignment must be 536870912 bytes or smaller; maximum alignment assumed}}
29+
void *align1073741824() {
30+
return test_ptr_alloc_align(2147483648); // expected-warning {{requested alignment must be 1073741824 bytes or smaller; maximum alignment assumed}}
3131
}

clang/test/Sema/attr-aligned.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s
22

33
int x __attribute__((aligned(3))); // expected-error {{requested alignment is not a power of 2}}
4-
int y __attribute__((aligned(1 << 30))); // expected-error {{requested alignment must be 536870912 bytes or smaller}}
4+
int y __attribute__((aligned(1 << 31))); // expected-error {{requested alignment must be 1073741824 bytes or smaller}}
55

66
// PR26444
77
int y __attribute__((aligned(1 << 29)));

0 commit comments

Comments
 (0)