Skip to content

Commit 94473f4

Browse files
authored
[IRBuilder] Generate nuw GEPs for struct member accesses (#99538)
Generate nuw GEPs for struct member accesses, as inbounds + non-negative implies nuw. Regression tests are updated using update scripts where possible, and by find + replace where not.
1 parent 38e0205 commit 94473f4

File tree

564 files changed

+38314
-38282
lines changed

Some content is hidden

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

564 files changed

+38314
-38282
lines changed

clang/lib/CodeGen/CGBuilder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,10 @@ class CGBuilderTy : public CGBuilderBaseTy {
210210
/// Given
211211
/// %addr = {T1, T2...}* ...
212212
/// produce
213-
/// %name = getelementptr inbounds %addr, i32 0, i32 index
213+
/// %name = getelementptr inbounds nuw %addr, i32 0, i32 index
214214
///
215215
/// This API assumes that drilling into a struct like this is always an
216-
/// inbounds operation.
216+
/// inbounds and nuw operation.
217217
using CGBuilderBaseTy::CreateStructGEP;
218218
Address CreateStructGEP(Address Addr, unsigned Index,
219219
const llvm::Twine &Name = "") {

clang/test/C/C2y/n3254.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ struct S {
2727
// CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
2828
// CHECK-NEXT: store ptr [[ARRAYDECAY]], ptr [[S_PTR]], align 8
2929
// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_PTR]], align 8
30-
// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[TMP0]], i32 0, i32 0
30+
// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[TMP0]], i32 0, i32 0
3131
// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[X]], align 4
3232
// CHECK-NEXT: ret i32 [[TMP1]]
3333
//
@@ -42,10 +42,10 @@ int foo() {
4242
// CHECK-NEXT: [[ENTRY:.*:]]
4343
// CHECK-NEXT: [[BUFFER:%.*]] = alloca [12 x i8], align 4
4444
// CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
45-
// CHECK-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 1
45+
// CHECK-NEXT: [[C:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 1
4646
// CHECK-NEXT: store i8 97, ptr [[C]], align 4
4747
// CHECK-NEXT: [[ARRAYDECAY1:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
48-
// CHECK-NEXT: [[C2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYDECAY1]], i32 0, i32 1
48+
// CHECK-NEXT: [[C2:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[ARRAYDECAY1]], i32 0, i32 1
4949
// CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[C2]], align 4
5050
// CHECK-NEXT: ret i8 [[TMP0]]
5151
//
@@ -60,10 +60,10 @@ char bar() {
6060
// CHECK-NEXT: [[ENTRY:.*:]]
6161
// CHECK-NEXT: [[BUFFER:%.*]] = alloca [12 x i8], align 4
6262
// CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
63-
// CHECK-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 2
63+
// CHECK-NEXT: [[F:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 2
6464
// CHECK-NEXT: store float 3.000000e+00, ptr [[F]], align 4
6565
// CHECK-NEXT: [[ARRAYDECAY1:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
66-
// CHECK-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYDECAY1]], i32 0, i32 2
66+
// CHECK-NEXT: [[F2:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[ARRAYDECAY1]], i32 0, i32 2
6767
// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[F2]], align 4
6868
// CHECK-NEXT: ret float [[TMP0]]
6969
//
@@ -83,11 +83,11 @@ struct T {
8383
// CHECK-NEXT: [[T:%.*]] = alloca [[STRUCT_T:%.*]], align 4
8484
// CHECK-NEXT: [[S_PTR:%.*]] = alloca ptr, align 8
8585
// CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[T]], i8 0, i64 12, i1 false)
86-
// CHECK-NEXT: [[BUFFER:%.*]] = getelementptr inbounds [[STRUCT_T]], ptr [[T]], i32 0, i32 0
86+
// CHECK-NEXT: [[BUFFER:%.*]] = getelementptr inbounds nuw [[STRUCT_T]], ptr [[T]], i32 0, i32 0
8787
// CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
8888
// CHECK-NEXT: store ptr [[ARRAYDECAY]], ptr [[S_PTR]], align 8
8989
// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_PTR]], align 8
90-
// CHECK-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[TMP0]], i32 0, i32 1
90+
// CHECK-NEXT: [[C:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[TMP0]], i32 0, i32 1
9191
// CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C]], align 4
9292
// CHECK-NEXT: ret i8 [[TMP1]]
9393
//
@@ -107,11 +107,11 @@ char quux() {
107107
// CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
108108
// CHECK-NEXT: store ptr [[ARRAYDECAY]], ptr [[T_PTR]], align 8
109109
// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[T_PTR]], align 8
110-
// CHECK-NEXT: [[BUFFER1:%.*]] = getelementptr inbounds [[STRUCT_T:%.*]], ptr [[TMP0]], i32 0, i32 0
110+
// CHECK-NEXT: [[BUFFER1:%.*]] = getelementptr inbounds nuw [[STRUCT_T:%.*]], ptr [[TMP0]], i32 0, i32 0
111111
// CHECK-NEXT: [[ARRAYDECAY2:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER1]], i64 0, i64 0
112112
// CHECK-NEXT: store ptr [[ARRAYDECAY2]], ptr [[S_PTR]], align 8
113113
// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[S_PTR]], align 8
114-
// CHECK-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[TMP1]], i32 0, i32 2
114+
// CHECK-NEXT: [[F:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[TMP1]], i32 0, i32 2
115115
// CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[F]], align 4
116116
// CHECK-NEXT: ret float [[TMP2]]
117117
//
@@ -128,16 +128,16 @@ float quibble() {
128128
// CHECK-NEXT: [[BUFFER:%.*]] = alloca [12 x i8], align 4
129129
// CHECK-NEXT: [[S_PTR:%.*]] = alloca ptr, align 8
130130
// CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
131-
// CHECK-NEXT: [[BUFFER1:%.*]] = getelementptr inbounds [[STRUCT_T:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 0
131+
// CHECK-NEXT: [[BUFFER1:%.*]] = getelementptr inbounds nuw [[STRUCT_T:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 0
132132
// CHECK-NEXT: [[ARRAYDECAY2:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER1]], i64 0, i64 0
133-
// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[ARRAYDECAY2]], i32 0, i32 0
133+
// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[ARRAYDECAY2]], i32 0, i32 0
134134
// CHECK-NEXT: store i32 12, ptr [[X]], align 4
135135
// CHECK-NEXT: [[ARRAYDECAY3:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
136-
// CHECK-NEXT: [[BUFFER4:%.*]] = getelementptr inbounds [[STRUCT_T]], ptr [[ARRAYDECAY3]], i32 0, i32 0
136+
// CHECK-NEXT: [[BUFFER4:%.*]] = getelementptr inbounds nuw [[STRUCT_T]], ptr [[ARRAYDECAY3]], i32 0, i32 0
137137
// CHECK-NEXT: [[ARRAYDECAY5:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER4]], i64 0, i64 0
138138
// CHECK-NEXT: store ptr [[ARRAYDECAY5]], ptr [[S_PTR]], align 8
139139
// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_PTR]], align 8
140-
// CHECK-NEXT: [[X6:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[TMP0]], i32 0, i32 0
140+
// CHECK-NEXT: [[X6:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[TMP0]], i32 0, i32 0
141141
// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[X6]], align 4
142142
// CHECK-NEXT: ret i32 [[TMP1]]
143143
//

clang/test/C/C2y/n3259.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,52 +12,52 @@ void test() {
1212
// CHECK: store float 0
1313
_Complex float f = __builtin_complex(1.0f, 0.0f);
1414

15-
// CHECK: %[[F_REALP1:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
15+
// CHECK: %[[F_REALP1:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
1616
// CHECK-NEXT: %[[F_REAL:.+]] = load float, ptr %[[F_REALP1]]
17-
// CHECK-NEXT: %[[F_IMAGP2:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
17+
// CHECK-NEXT: %[[F_IMAGP2:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
1818
// CHECK-NEXT: %[[F_IMAG:.+]] = load float, ptr %[[F_IMAGP2]]
1919
// CHECK-NEXT: %[[INC:.+]] = fadd float %[[F_REAL]], 1.000000e+00
20-
// CHECK-NEXT: %[[F_REALP3:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
21-
// CHECK-NEXT: %[[F_IMAGP4:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
20+
// CHECK-NEXT: %[[F_REALP3:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
21+
// CHECK-NEXT: %[[F_IMAGP4:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
2222
// CHECK-NEXT: store float %[[INC]], ptr %[[F_REALP3]]
2323
// CHECK-NEXT: store float %[[F_IMAG]], ptr %[[F_IMAGP4]]
2424
f++; /* expected-warning {{'++' on an object of complex type is a C2y extension}}
2525
pre-c2y-warning {{'++' on an object of complex type is incompatible with C standards before C2y}}
2626
*/
2727

28-
// CHECK: %[[F_REALP5:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
28+
// CHECK: %[[F_REALP5:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
2929
// CHECK-NEXT: %[[F_REAL6:.+]] = load float, ptr %[[F_REALP5]]
30-
// CHECK-NEXT: %[[F_IMAGP7:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
30+
// CHECK-NEXT: %[[F_IMAGP7:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
3131
// CHECK-NEXT: %[[F_IMAG8:.+]] = load float, ptr %[[F_IMAGP7]]
3232
// CHECK-NEXT: %[[INC9:.+]] = fadd float %[[F_REAL6]], 1.000000e+00
33-
// CHECK-NEXT: %[[F_REALP10:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
34-
// CHECK-NEXT: %[[F_IMAGP11:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
33+
// CHECK-NEXT: %[[F_REALP10:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
34+
// CHECK-NEXT: %[[F_IMAGP11:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
3535
// CHECK-NEXT: store float %[[INC9]], ptr %[[F_REALP10]]
3636
// CHECK-NEXT: store float %[[F_IMAG8]], ptr %[[F_IMAGP11]]
3737
++f; /* expected-warning {{'++' on an object of complex type is a C2y extension}}
3838
pre-c2y-warning {{'++' on an object of complex type is incompatible with C standards before C2y}}
3939
*/
4040

41-
// CHECK: %[[F_REALP12:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
41+
// CHECK: %[[F_REALP12:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
4242
// CHECK-NEXT: %[[F_REAL13:.+]] = load float, ptr %[[F_REALP12]]
43-
// CHECK-NEXT: %[[F_IMAGP14:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
43+
// CHECK-NEXT: %[[F_IMAGP14:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
4444
// CHECK-NEXT: %[[F_IMAG15:.+]] = load float, ptr %[[F_IMAGP14]]
4545
// CHECK-NEXT: %[[DEC:.+]] = fadd float %[[F_REAL13]], -1.000000e+00
46-
// CHECK-NEXT: %[[F_REALP16:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
47-
// CHECK-NEXT: %[[F_IMAGP17:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
46+
// CHECK-NEXT: %[[F_REALP16:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
47+
// CHECK-NEXT: %[[F_IMAGP17:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
4848
// CHECK-NEXT: store float %[[DEC]], ptr %[[F_REALP16]]
4949
// CHECK-NEXT: store float %[[F_IMAG15]], ptr %[[F_IMAGP17]]
5050
f--; /* expected-warning {{'--' on an object of complex type is a C2y extension}}
5151
pre-c2y-warning {{'--' on an object of complex type is incompatible with C standards before C2y}}
5252
*/
5353

54-
// CHECK: %[[F_REALP18:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
54+
// CHECK: %[[F_REALP18:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
5555
// CHECK-NEXT: %[[F_REAL19:.+]] = load float, ptr %[[F_REALP18]]
56-
// CHECK-NEXT: %[[F_IMAGP20:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
56+
// CHECK-NEXT: %[[F_IMAGP20:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
5757
// CHECK-NEXT: %[[F_IMAG21:.+]] = load float, ptr %[[F_IMAGP20]]
5858
// CHECK-NEXT: %[[DEC22:.+]] = fadd float %[[F_REAL19]], -1.000000e+00
59-
// CHECK-NEXT: %[[F_REALP23:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
60-
// CHECK-NEXT: %[[F_IMAGP24:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
59+
// CHECK-NEXT: %[[F_REALP23:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
60+
// CHECK-NEXT: %[[F_IMAGP24:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
6161
// CHECK-NEXT: store float %[[DEC22]], ptr %[[F_REALP23]]
6262
// CHECK-NEXT: store float %[[F_IMAG21]], ptr %[[F_IMAGP24]]
6363
--f; /* expected-warning {{'--' on an object of complex type is a C2y extension}}

0 commit comments

Comments
 (0)