[llvm-branch-commits] [clang] [CIR] Emit inbounds nuw flags on GetMemberOp GEP lowering (PR #186738)
Henrich Lauko via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Mar 15 22:49:17 PDT 2026
https://github.com/xlauko created https://github.com/llvm/llvm-project/pull/186738
Struct member accesses via GetMemberOp are always inbounds and cannot
unsigned-wrap, matching LLVM's IRBuilder::CreateStructGEP behavior.
>From 6cf0e467e0547cc939dfc5335104b6ceaa8798ec Mon Sep 17 00:00:00 2001
From: xlauko <xlauko at mail.muni.cz>
Date: Mon, 16 Mar 2026 06:46:00 +0100
Subject: [PATCH] [CIR] Emit inbounds nuw flags on GetMemberOp GEP lowering
Struct member accesses via GetMemberOp are always inbounds and cannot
unsigned-wrap, matching LLVM's IRBuilder::CreateStructGEP behavior.
---
.../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 10 +++++--
.../CIR/CodeGen/aapcs-volatile-bitfields.c | 14 +++++-----
.../CIR/CodeGen/aggregate-copy-overlap.cpp | 4 +--
clang/test/CIR/CodeGen/atomic-thread-fence.c | 8 +++---
clang/test/CIR/CodeGen/bitfields.c | 18 ++++++------
clang/test/CIR/CodeGen/bitfields.cpp | 8 +++---
clang/test/CIR/CodeGen/bitfields_be.c | 8 +++---
.../CodeGen/call-via-class-member-funcptr.cpp | 4 +--
clang/test/CIR/CodeGen/class.cpp | 6 ++--
clang/test/CIR/CodeGen/complex.cpp | 2 +-
clang/test/CIR/CodeGen/copy-constructor.cpp | 4 +--
clang/test/CIR/CodeGen/cxx-default-init.cpp | 28 +++++++++----------
clang/test/CIR/CodeGen/delete.cpp | 2 +-
clang/test/CIR/CodeGen/dtors.cpp | 2 +-
clang/test/CIR/CodeGen/inline-asm.c | 4 +--
clang/test/CIR/CodeGen/inline-cxx-func.cpp | 2 +-
clang/test/CIR/CodeGen/instantiate-init.cpp | 4 +--
clang/test/CIR/CodeGen/lambda.cpp | 26 ++++++++---------
clang/test/CIR/CodeGen/no-unique-address.cpp | 2 +-
clang/test/CIR/CodeGen/statement-exprs.c | 2 +-
clang/test/CIR/CodeGen/struct-init.cpp | 12 ++++----
clang/test/CIR/CodeGen/struct.c | 12 ++++----
clang/test/CIR/CodeGen/struct.cpp | 22 +++++++--------
.../CIR/CodeGen/variable-decomposition.cpp | 4 +--
clang/test/CIR/CodeGen/volatile.cpp | 16 +++++------
25 files changed, 115 insertions(+), 109 deletions(-)
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 4a1b4292b23dd..062739d85991f 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -3713,8 +3713,14 @@ mlir::LogicalResult CIRToLLVMGetMemberOpLowering::matchAndRewrite(
// is always zero. The second offset tell us which member it will access.
llvm::SmallVector<mlir::LLVM::GEPArg, 2> offset{0, op.getIndex()};
const mlir::Type elementTy = getTypeConverter()->convertType(recordTy);
- rewriter.replaceOpWithNewOp<mlir::LLVM::GEPOp>(op, llResTy, elementTy,
- adaptor.getAddr(), offset);
+ // Struct member accesses are always inbounds and nuw: the base pointer
+ // is valid and the member offset is a positive, constant offset within
+ // the struct layout, so it cannot wrap. This matches LLVM's
+ // IRBuilder::CreateStructGEP.
+ mlir::LLVM::GEPNoWrapFlags flags =
+ mlir::LLVM::GEPNoWrapFlags::inbounds | mlir::LLVM::GEPNoWrapFlags::nuw;
+ rewriter.replaceOpWithNewOp<mlir::LLVM::GEPOp>(
+ op, llResTy, elementTy, adaptor.getAddr(), offset, flags);
return mlir::success();
}
case cir::RecordType::Union:
diff --git a/clang/test/CIR/CodeGen/aapcs-volatile-bitfields.c b/clang/test/CIR/CodeGen/aapcs-volatile-bitfields.c
index 5218a29848fb0..ecde8f24b2334 100644
--- a/clang/test/CIR/CodeGen/aapcs-volatile-bitfields.c
+++ b/clang/test/CIR/CodeGen/aapcs-volatile-bitfields.c
@@ -93,7 +93,7 @@ int check_load(st1 *s1) {
// LLVM:define dso_local i32 @check_load
// LLVM: [[LOAD:%.*]] = load ptr, ptr {{.*}}, align 8
-// LLVM: [[MEMBER:%.*]] = getelementptr %struct.st1, ptr [[LOAD]], i32 0, i32 0
+// LLVM: [[MEMBER:%.*]] = getelementptr inbounds nuw %struct.st1, ptr [[LOAD]], i32 0, i32 0
// LLVM: [[LOADVOL:%.*]] = load volatile i32, ptr [[MEMBER]], align 4
// LLVM: [[LSHR:%.*]] = lshr i32 [[LOADVOL]], 9
// LLVM: [[CLEAR:%.*]] = and i32 [[LSHR]], 1
@@ -125,7 +125,7 @@ int check_load_exception(st3 *s3) {
// LLVM:define dso_local i32 @check_load_exception
// LLVM: [[LOAD:%.*]] = load ptr, ptr {{.*}}, align 8
-// LLVM: [[MEMBER:%.*]] = getelementptr %struct.st3, ptr [[LOAD]], i32 0, i32 2
+// LLVM: [[MEMBER:%.*]] = getelementptr inbounds nuw %struct.st3, ptr [[LOAD]], i32 0, i32 2
// LLVM: [[LOADVOL:%.*]] = load volatile i8, ptr [[MEMBER]], align 4
// LLVM: [[CLEAR:%.*]] = and i8 [[LOADVOL]], 31
// LLVM: [[CAST:%.*]] = zext i8 [[CLEAR]] to i32
@@ -161,7 +161,7 @@ int clip_load_exception2(clip *c) {
// LLVM:define dso_local i32 @clip_load_exception2
// LLVM: [[LOAD:%.*]] = load ptr, ptr {{.*}}, align 8
-// LLVM: [[MEMBER:%.*]] = getelementptr %struct.clip, ptr [[LOAD]], i32 0, i32 0
+// LLVM: [[MEMBER:%.*]] = getelementptr inbounds nuw %struct.clip, ptr [[LOAD]], i32 0, i32 0
// LLVM: [[LOADVOL:%.*]] = load volatile i24, ptr [[MEMBER]], align 4
// LLVM: [[CAST:%.*]] = sext i24 [[LOADVOL]] to i32
// LLVM: store i32 [[CAST]], ptr [[RETVAL:%.*]], align 4
@@ -187,7 +187,7 @@ void check_store(st2 *s2) {
// LLVM:define dso_local void @check_store
// LLVM: [[LOAD:%.*]] = load ptr, ptr {{.*}}, align 8
-// LLVM: [[MEMBER:%.*]] = getelementptr %struct.st2, ptr [[LOAD]], i32 0, i32 0
+// LLVM: [[MEMBER:%.*]] = getelementptr inbounds nuw %struct.st2, ptr [[LOAD]], i32 0, i32 0
// LLVM: [[LOADVOL:%.*]] = load volatile i16, ptr [[MEMBER]], align 8
// LLVM: [[CLEAR:%.*]] = and i16 [[LOADVOL]], -8
// LLVM: [[SET:%.*]] = or i16 [[CLEAR]], 1
@@ -217,7 +217,7 @@ void check_store_exception(st3 *s3) {
// LLVM:define dso_local void @check_store_exception
// LLVM: [[LOAD:%.*]] = load ptr, ptr {{.*}}, align 8
-// LLVM: [[MEMBER:%.*]] = getelementptr %struct.st3, ptr [[LOAD]], i32 0, i32 2
+// LLVM: [[MEMBER:%.*]] = getelementptr inbounds nuw %struct.st3, ptr [[LOAD]], i32 0, i32 2
// LLVM: [[LOADVOL:%.*]] = load volatile i8, ptr [[MEMBER]], align 4
// LLVM: [[CLEAR:%.*]] = and i8 [[LOADVOL]], -32
// LLVM: [[SET:%.*]] = or i8 [[CLEAR]], 2
@@ -246,7 +246,7 @@ void clip_store_exception2(clip *c) {
// LLVM:define dso_local void @clip_store_exception2
// LLVM: [[LOAD:%.*]] = load ptr, ptr {{.*}}, align 8
-// LLVM: [[MEMBER:%.*]] = getelementptr %struct.clip, ptr [[LOAD]], i32 0, i32 0
+// LLVM: [[MEMBER:%.*]] = getelementptr inbounds nuw %struct.clip, ptr [[LOAD]], i32 0, i32 0
// LLVM: store volatile i24 3, ptr [[MEMBER]], align 4
// LLVM: ret void
@@ -267,7 +267,7 @@ void check_store_second_member (st4 *s4) {
// LLVM: define dso_local void @check_store_second_member
// LLVM: [[LOAD:%.*]] = load ptr, ptr {{.*}}, align 8
-// LLVM: [[MEMBER:%.*]] = getelementptr %struct.st4, ptr [[LOAD]], i32 0, i32 2
+// LLVM: [[MEMBER:%.*]] = getelementptr inbounds nuw %struct.st4, ptr [[LOAD]], i32 0, i32 2
// LLVM: [[VAL:%.*]] = load volatile i64, ptr [[MEMBER]], align 8
// LLVM: [[CLEAR:%.*]] = and i64 [[VAL]], -65536
// LLVM: [[SET:%.*]] = or i64 [[CLEAR]], 1
diff --git a/clang/test/CIR/CodeGen/aggregate-copy-overlap.cpp b/clang/test/CIR/CodeGen/aggregate-copy-overlap.cpp
index bcad743a2c9db..507bdad91b4cd 100644
--- a/clang/test/CIR/CodeGen/aggregate-copy-overlap.cpp
+++ b/clang/test/CIR/CodeGen/aggregate-copy-overlap.cpp
@@ -41,7 +41,7 @@ struct Outer : virtual VBase {
// CIR-NEXT: cir.libc.memcpy %[[SIZE]] bytes from %[[SRC]] to %[[DST]]
// LLVM-LABEL: define {{.*}} void @_ZN5OuterC1ERK10HasPaddingc(
-// LLVM: %[[GEP:.*]] = getelementptr %struct.Outer, ptr %{{.+}}, i32 0, i32 1
+// LLVM: %[[GEP:.*]] = getelementptr inbounds nuw %struct.Outer, ptr %{{.+}}, i32 0, i32 1
// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %[[GEP]], ptr %{{.+}}, i64 5, i1 false)
// OGCG-LABEL: define {{.*}} void @_ZN5OuterC1ERK10HasPaddingc(
@@ -64,7 +64,7 @@ struct NonOverlapping {
// CIR: cir.copy %{{.+}} to %{{.+}} : !cir.ptr<!rec_HasPadding>
// LLVM-LABEL: define {{.*}} void @_ZN14NonOverlappingC2ERK10HasPaddingc(
-// LLVM: %[[GEP:.*]] = getelementptr %struct.NonOverlapping, ptr %{{.+}}, i32 0, i32 0
+// LLVM: %[[GEP:.*]] = getelementptr inbounds nuw %struct.NonOverlapping, ptr %{{.+}}, i32 0, i32 0
// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %[[GEP]], ptr %{{.+}}, i64 8, i1 false)
// OGCG-LABEL: define {{.*}} void @_ZN14NonOverlappingC2ERK10HasPaddingc(
diff --git a/clang/test/CIR/CodeGen/atomic-thread-fence.c b/clang/test/CIR/CodeGen/atomic-thread-fence.c
index eced95b1e6e59..bca91a61d8d24 100644
--- a/clang/test/CIR/CodeGen/atomic-thread-fence.c
+++ b/clang/test/CIR/CodeGen/atomic-thread-fence.c
@@ -58,7 +58,7 @@ void modifyWithThreadFence(DataPtr d) {
// LLVM: %[[DATA:.*]] = alloca ptr, i64 1, align 8
// LLVM: fence seq_cst
// LLVM: %[[DATA_PTR:.*]] = load ptr, ptr %[[DATA]], align 8
- // LLVM: %[[DATA_VALUE:.*]] = getelementptr %struct.Data, ptr %[[DATA_PTR]], i32 0, i32 0
+ // LLVM: %[[DATA_VALUE:.*]] = getelementptr inbounds nuw %struct.Data, ptr %[[DATA_PTR]], i32 0, i32 0
// LLVM: store i32 42, ptr %[[DATA_VALUE]], align 8
// LLVM: ret void
@@ -87,7 +87,7 @@ void modifyWithSignalFence(DataPtr d) {
// LLVM: %[[DATA:.*]] = alloca ptr, i64 1, align 8
// LLVM: fence syncscope("singlethread") seq_cst
// LLVM: %[[DATA_PTR:.*]] = load ptr, ptr %[[DATA]], align 8
- // LLVM: %[[DATA_VALUE:.*]] = getelementptr %struct.Data, ptr %[[DATA_PTR]], i32 0, i32 0
+ // LLVM: %[[DATA_VALUE:.*]] = getelementptr inbounds nuw %struct.Data, ptr %[[DATA_PTR]], i32 0, i32 0
// LLVM: store i32 24, ptr %[[DATA_VALUE]], align 8
// LLVM: ret void
@@ -119,7 +119,7 @@ void loadWithThreadFence(DataPtr d) {
// LLVM: %[[DATA_TEMP:.*]] = alloca ptr, i64 1, align 8
// LLVM: fence seq_cst
// LLVM: %[[DATA_PTR:.*]] = load ptr, ptr %[[DATA]], align 8
- // LLVM: %[[DATA_VALUE:.*]] = getelementptr %struct.Data, ptr %[[DATA_PTR]], i32 0, i32 1
+ // LLVM: %[[DATA_VALUE:.*]] = getelementptr inbounds nuw %struct.Data, ptr %[[DATA_PTR]], i32 0, i32 1
// LLVM: %[[ATOMIC_LOAD:.*]] = load atomic ptr, ptr %[[DATA_VALUE]] seq_cst, align 8
// LLVM: store ptr %[[ATOMIC_LOAD]], ptr %[[DATA_TEMP]], align 8
// LLVM: %[[DATA_TEMP_LOAD:.*]] = load ptr, ptr %[[DATA_TEMP]], align 8
@@ -156,7 +156,7 @@ void loadWithSignalFence(DataPtr d) {
// LLVM: %[[DATA_TEMP:.*]] = alloca ptr, i64 1, align 8
// LLVM: fence syncscope("singlethread") seq_cst
// LLVM: %[[DATA_PTR:.*]] = load ptr, ptr %[[DATA]], align 8
- // LLVM: %[[DATA_VALUE:.*]] = getelementptr %struct.Data, ptr %[[DATA_PTR]], i32 0, i32 1
+ // LLVM: %[[DATA_VALUE:.*]] = getelementptr inbounds nuw %struct.Data, ptr %[[DATA_PTR]], i32 0, i32 1
// LLVM: %[[ATOMIC_LOAD:.*]] = load atomic ptr, ptr %[[DATA_VALUE]] seq_cst, align 8
// LLVM: store ptr %[[ATOMIC_LOAD]], ptr %[[DATA_TEMP]], align 8
// LLVM: %[[DATA_TEMP_LOAD]] = load ptr, ptr %[[DATA_TEMP]], align 8
diff --git a/clang/test/CIR/CodeGen/bitfields.c b/clang/test/CIR/CodeGen/bitfields.c
index 7d86bc36a31e6..be76fb4da2644 100644
--- a/clang/test/CIR/CodeGen/bitfields.c
+++ b/clang/test/CIR/CodeGen/bitfields.c
@@ -104,7 +104,7 @@ int load_field(S* s) {
// LLVM: [[TMP0:%.*]] = alloca ptr, i64 1, align 8
// LLVM: [[TMP1:%.*]] = alloca i32, i64 1, align 4
// LLVM: [[TMP2:%.*]] = load ptr, ptr [[TMP0]], align 8
-// LLVM: [[TMP3:%.*]] = getelementptr %struct.S, ptr [[TMP2]], i32 0, i32 0
+// LLVM: [[TMP3:%.*]] = getelementptr inbounds nuw %struct.S, ptr [[TMP2]], i32 0, i32 0
// LLVM: [[TMP4:%.*]] = load i64, ptr [[TMP3]], align 4
// LLVM: [[TMP5:%.*]] = shl i64 [[TMP4]], 15
// LLVM: [[TMP6:%.*]] = ashr i64 [[TMP5]], 47
@@ -131,7 +131,7 @@ unsigned int load_field_unsigned(A* s) {
//LLVM: define dso_local i32 @load_field_unsigned
//LLVM: [[TMP0:%.*]] = alloca ptr, i64 1, align 8
//LLVM: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8
-//LLVM: [[TMP2:%.*]] = getelementptr %struct.A, ptr [[TMP1]], i32 0, i32 3
+//LLVM: [[TMP2:%.*]] = getelementptr inbounds nuw %struct.A, ptr [[TMP1]], i32 0, i32 3
//LLVM: [[TMP3:%.*]] = load i16, ptr [[TMP2]], align 1
//LLVM: [[TMP4:%.*]] = lshr i16 [[TMP3]], 3
//LLVM: [[TMP5:%.*]] = and i16 [[TMP4]], 15
@@ -158,7 +158,7 @@ void store_field() {
// LLVM: define dso_local void @store_field()
// LLVM: [[TMP0:%.*]] = alloca %struct.S, i64 1, align 4
-// LLVM: [[TMP1:%.*]] = getelementptr %struct.S, ptr [[TMP0]], i32 0, i32 1
+// LLVM: [[TMP1:%.*]] = getelementptr inbounds nuw %struct.S, ptr [[TMP0]], i32 0, i32 1
// LLVM: [[TMP2:%.*]] = load i16, ptr [[TMP1]], align 4
// LLVM: [[TMP3:%.*]] = and i16 [[TMP2]], -32768
// LLVM: [[TMP4:%.*]] = or i16 [[TMP3]], 3
@@ -186,12 +186,12 @@ void store_bitfield_to_bitfield() {
// LLVM: define dso_local void @store_bitfield_to_bitfield()
// LLVM: [[TMP0:%.*]] = alloca %struct.S, i64 1, align 4
-// LLVM: [[TMP1:%.*]] = getelementptr %struct.S, ptr [[TMP0]], i32 0, i32 0
+// LLVM: [[TMP1:%.*]] = getelementptr inbounds nuw %struct.S, ptr [[TMP0]], i32 0, i32 0
// LLVM: [[TMP2:%.*]] = load i64, ptr [[TMP1]], align 4
// LLVM: [[TMP3:%.*]] = shl i64 [[TMP2]], 15
// LLVM: [[TMP4:%.*]] = ashr i64 [[TMP3]], 47
// LLVM: [[TMP5:%.*]] = trunc i64 [[TMP4]] to i32
-// LLVM: [[TMP6:%.*]] = getelementptr %struct.S, ptr [[TMP0]], i32 0, i32 0
+// LLVM: [[TMP6:%.*]] = getelementptr inbounds nuw %struct.S, ptr [[TMP0]], i32 0, i32 0
// LLVM: [[TMP7:%.*]] = zext i32 [[TMP5]] to i64
// LLVM: [[TMP8:%.*]] = load i64, ptr [[TMP6]], align 4
// LLVM: [[TMP9:%.*]] = and i64 [[TMP7]], 15
@@ -238,7 +238,7 @@ void get_volatile(V* v) {
// LLVM: define dso_local void @get_volatile
// LLVM: [[TMP0:%.*]] = alloca ptr, i64 1, align 8
// LLVM: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8
-// LLVM: [[TMP2:%.*]] = getelementptr %struct.V, ptr [[TMP1]], i32 0, i32 0
+// LLVM: [[TMP2:%.*]] = getelementptr inbounds nuw %struct.V, ptr [[TMP1]], i32 0, i32 0
// LLVM: [[TMP3:%.*]] = load volatile i64, ptr [[TMP2]], align 4
// LLVM: [[TMP4:%.*]] = and i64 [[TMP3]], -1095216660481
// LLVM: [[TMP5:%.*]] = or i64 [[TMP4]], 12884901888
@@ -265,7 +265,7 @@ void set_volatile(V* v) {
// LLVM: define dso_local void @set_volatile
// LLVM: [[TMP0:%.*]] = alloca ptr, i64 1, align 8
// LLVM: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8
-// LLVM: [[TMP2:%.*]] = getelementptr %struct.V, ptr [[TMP1]], i32 0, i32 0
+// LLVM: [[TMP2:%.*]] = getelementptr inbounds nuw %struct.V, ptr [[TMP1]], i32 0, i32 0
// LLVM: [[TMP3:%.*]] = load volatile i64, ptr [[TMP2]], align 4
// LLVM: [[TMP4:%.*]] = and i64 [[TMP3]], -1095216660481
// LLVM: [[TMP5:%.*]] = or i64 [[TMP4]], 12884901888
@@ -292,7 +292,7 @@ void unOp(S* s) {
// CIR: cir.set_bitfield align(4) (#bfi_d, [[TMP2]] : !cir.ptr<!u64i>, [[TMP4]] : !s32i)
// LLVM: define {{.*@unOp}}
-// LLVM: [[TMP0:%.*]] = getelementptr %struct.S, ptr [[LOAD0:%.*]], i32 0, i32 0
+// LLVM: [[TMP0:%.*]] = getelementptr inbounds nuw %struct.S, ptr [[LOAD0:%.*]], i32 0, i32 0
// LLVM: [[TMP1:%.*]] = load i64, ptr [[TMP0]], align 4
// LLVM: [[TMP2:%.*]] = shl i64 [[TMP1]], 13
// LLVM: [[TMP3:%.*]] = ashr i64 [[TMP2]], 62
@@ -340,7 +340,7 @@ void binOp(S* s) {
// LLVM: define {{.*@binOp}}
// LLVM: [[TMP0:%.*]] = load ptr, ptr {{.*}}, align 8
-// LLVM: [[TMP1:%.*]] = getelementptr %struct.S, ptr [[TMP0]], i32 0, i32 0
+// LLVM: [[TMP1:%.*]] = getelementptr inbounds nuw %struct.S, ptr [[TMP0]], i32 0, i32 0
// LLVM: [[TMP2:%.*]] = load i64, ptr [[TMP1]], align 4
// LLVM: [[TMP3:%.*]] = shl i64 [[TMP2]], 13
// LLVM: [[TMP4:%.*]] = ashr i64 [[TMP3]], 62
diff --git a/clang/test/CIR/CodeGen/bitfields.cpp b/clang/test/CIR/CodeGen/bitfields.cpp
index 04e06b37d6e00..d91c5af275400 100644
--- a/clang/test/CIR/CodeGen/bitfields.cpp
+++ b/clang/test/CIR/CodeGen/bitfields.cpp
@@ -45,7 +45,7 @@ int load_field(S* s) {
// LLVM: [[TMP0:%.*]] = alloca ptr, i64 1, align 8
// LLVM: [[TMP1:%.*]] = alloca i32, i64 1, align 4
// LLVM: [[TMP2:%.*]] = load ptr, ptr [[TMP0]], align 8
-// LLVM: [[TMP3:%.*]] = getelementptr %struct.S, ptr [[TMP2]], i32 0, i32 0
+// LLVM: [[TMP3:%.*]] = getelementptr inbounds nuw %struct.S, ptr [[TMP2]], i32 0, i32 0
// LLVM: [[TMP4:%.*]] = load i64, ptr [[TMP3]], align 4
// LLVM: [[TMP5:%.*]] = shl i64 [[TMP4]], 15
// LLVM: [[TMP6:%.*]] = ashr i64 [[TMP5]], 47
@@ -71,7 +71,7 @@ void store_field() {
// LLVM: define dso_local void @_Z11store_fieldv
// LLVM: [[TMP0:%.*]] = alloca %struct.S, i64 1, align 4
-// LLVM: [[TMP1:%.*]] = getelementptr %struct.S, ptr [[TMP0]], i32 0, i32 0
+// LLVM: [[TMP1:%.*]] = getelementptr inbounds nuw %struct.S, ptr [[TMP0]], i32 0, i32 0
// LLVM: [[TMP2:%.*]] = load i64, ptr [[TMP1]], align 4
// LLVM: [[TMP3:%.*]] = and i64 [[TMP2]], -16
// LLVM: [[TMP4:%.*]] = or i64 [[TMP3]], 3
@@ -101,13 +101,13 @@ void store_bitfield_to_bitfield(S* s) {
// LLVM: define dso_local void @_Z26store_bitfield_to_bitfieldP1S
// LLVM: [[TMP0:%.*]] = alloca ptr, i64 1, align 8
// LLVM: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8
-// LLVM: [[TMP2:%.*]] = getelementptr %struct.S, ptr [[TMP1]], i32 0, i32 0
+// LLVM: [[TMP2:%.*]] = getelementptr inbounds nuw %struct.S, ptr [[TMP1]], i32 0, i32 0
// LLVM: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 4
// LLVM: [[TMP4:%.*]] = and i64 [[TMP3]], -2147483633
// LLVM: [[TMP5:%.*]] = or i64 [[TMP4]], 48
// LLVM: store i64 [[TMP5]], ptr [[TMP2]], align 4
// LLVM: [[TMP6:%.*]] = load ptr, ptr [[TMP0]], align 8
-// LLVM: [[TMP7:%.*]] = getelementptr %struct.S, ptr [[TMP6]], i32 0, i32 0
+// LLVM: [[TMP7:%.*]] = getelementptr inbounds nuw %struct.S, ptr [[TMP6]], i32 0, i32 0
// LLVM: [[TMP8:%.*]] = load i64, ptr [[TMP7]], align 4
// LLVM: [[TMP9:%.*]] = and i64 [[TMP8]], -16
// LLVM: [[TMP10:%.*]] = or i64 [[TMP9]], 3
diff --git a/clang/test/CIR/CodeGen/bitfields_be.c b/clang/test/CIR/CodeGen/bitfields_be.c
index 79801a38df3db..3c8366a8d39c0 100644
--- a/clang/test/CIR/CodeGen/bitfields_be.c
+++ b/clang/test/CIR/CodeGen/bitfields_be.c
@@ -31,7 +31,7 @@ int init(S* s) {
//LLVM: [[TMP0:%.*]] = alloca ptr, i64 1, align 8
//LLVM: [[TMP1:%.*]] = alloca i32, i64 1, align 4
//LLVM: [[TMP2:%.*]] = load ptr, ptr [[TMP0]], align 8
-//LLVM: [[TMP3:%.*]] = getelementptr %struct.S, ptr [[TMP2]], i32 0, i32 0
+//LLVM: [[TMP3:%.*]] = getelementptr inbounds nuw %struct.S, ptr [[TMP2]], i32 0, i32 0
//LLVM: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4
//LLVM: [[TMP5:%.*]] = shl i32 [[TMP4]], 15
//LLVM: [[TMP6:%.*]] = ashr i32 [[TMP5]], 15
@@ -60,7 +60,7 @@ void load(S* s) {
// LLVM: define dso_local void @load{{.*}}{{.*}}
// LLVM: %[[PTR0:.*]] = load ptr
-// LLVM: %[[GET0:.*]] = getelementptr %struct.S, ptr %[[PTR0]], i32 0, i32 0
+// LLVM: %[[GET0:.*]] = getelementptr inbounds nuw %struct.S, ptr %[[PTR0]], i32 0, i32 0
// LLVM: %[[VAL0:.*]] = load i32, ptr %[[GET0]], align 4
// LLVM: %[[AND0:.*]] = and i32 %[[VAL0]], 268435455
// LLVM: %[[OR0:.*]] = or i32 %[[AND0]], -1073741824
@@ -80,7 +80,7 @@ void load(S* s) {
// CIR: %[[SET1:.*]] = cir.set_bitfield align(4) (#bfi_b, %[[GET1]] : !cir.ptr<!u32i>, %[[CONST2]] : !s32i) -> !s32i
// LLVM: %[[PTR1:.*]] = load ptr
-// LLVM: %[[GET1:.*]] = getelementptr %struct.S, ptr %[[PTR1]], i32 0, i32 0
+// LLVM: %[[GET1:.*]] = getelementptr inbounds nuw %struct.S, ptr %[[PTR1]], i32 0, i32 0
// LLVM: %[[VAL1:.*]] = load i32, ptr %[[GET1]], align 4
// LLVM: %[[AND1:.*]] = and i32 %[[VAL1]], -268304385
// LLVM: %[[OR1:.*]] = or i32 %[[AND1]], 5505024
@@ -99,7 +99,7 @@ void load(S* s) {
// CIR: %[[SET2:.*]] = cir.set_bitfield align(4) (#bfi_c, %[[GET2]] : !cir.ptr<!u32i>, %[[CONST3]] : !s32i) -> !s32i
// LLVM: %[[PTR2:.*]] = load ptr
-// LLVM: %[[GET2:.*]] = getelementptr %struct.S, ptr %[[PTR2]], i32 0, i32 0
+// LLVM: %[[GET2:.*]] = getelementptr inbounds nuw %struct.S, ptr %[[PTR2]], i32 0, i32 0
// LLVM: %[[VAL2:.*]] = load i32, ptr %[[GET2]], align 4
// LLVM: %[[AND2:.*]] = and i32 %[[VAL2]], -131072
// LLVM: %[[OR2:.*]] = or i32 %[[AND2]], 118727
diff --git a/clang/test/CIR/CodeGen/call-via-class-member-funcptr.cpp b/clang/test/CIR/CodeGen/call-via-class-member-funcptr.cpp
index 0e41324f3bfd8..de3369e169bb2 100644
--- a/clang/test/CIR/CodeGen/call-via-class-member-funcptr.cpp
+++ b/clang/test/CIR/CodeGen/call-via-class-member-funcptr.cpp
@@ -67,8 +67,8 @@ void fn2() { C c1; c1.call_indirect(2); }
// LLVM: store ptr %[[THIS_ARG]], ptr %[[THIS_ADDR]]
// LLVM: store i32 %[[V_ARG]], ptr %[[V_ADDR]]
// LLVM: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]
-// LLVM: %[[INNER:.*]] = getelementptr %class.C, ptr %[[THIS]], i32 0, i32 0
-// LLVM: %[[INDIRECT_CALLEE_PTR:.*]] = getelementptr %class.B, ptr %[[INNER]], i32 0, i32 0
+// LLVM: %[[INNER:.*]] = getelementptr inbounds nuw %class.C, ptr %[[THIS]], i32 0, i32 0
+// LLVM: %[[INDIRECT_CALLEE_PTR:.*]] = getelementptr inbounds nuw %class.B, ptr %[[INNER]], i32 0, i32 0
// LLVM: %[[INDIRECT_CALLEE:.*]] = load ptr, ptr %[[INDIRECT_CALLEE_PTR]]
// LLVM: %[[V:.*]] = load i32, ptr %[[V_ADDR]]
// LLVM: %[[RET:.*]] = call noundef i32 %[[INDIRECT_CALLEE]](i32 noundef %[[V]])
diff --git a/clang/test/CIR/CodeGen/class.cpp b/clang/test/CIR/CodeGen/class.cpp
index eb9d5d73c3616..243eb746ade52 100644
--- a/clang/test/CIR/CodeGen/class.cpp
+++ b/clang/test/CIR/CodeGen/class.cpp
@@ -59,7 +59,7 @@ int use(Derived *d) { return d->b; }
// CIR: %[[D_B:.*]] = cir.load align(4) %[[D_B_ADDR]]
// LLVM: define{{.*}} i32 @_Z3useP7Derived
-// LLVM: getelementptr %class.Derived, ptr %{{.*}}, i32 0, i32 1
+// LLVM: getelementptr inbounds nuw %class.Derived, ptr %{{.*}}, i32 0, i32 1
// OGCG: define{{.*}} i32 @_Z3useP7Derived
// OGCG: getelementptr inbounds nuw %class.Derived, ptr %{{.*}}, i32 0, i32 1
@@ -77,7 +77,7 @@ int use_base() {
// LLVM: define{{.*}} i32 @_Z8use_basev
// LLVM: %[[D:.*]] = alloca %class.Derived
-// LLVM: %[[D_A_ADDR:.*]] = getelementptr %class.Base, ptr %[[D]], i32 0, i32 0
+// LLVM: %[[D_A_ADDR:.*]] = getelementptr inbounds nuw %class.Base, ptr %[[D]], i32 0, i32 0
// OGCG: define{{.*}} i32 @_Z8use_basev
// OGCG: %[[D:.*]] = alloca %class.Derived
@@ -96,7 +96,7 @@ int use_base_via_pointer(Derived *d) {
// CIR: %[[D_A:.*]] = cir.load align(4) %[[D_A_ADDR]]
// LLVM: define{{.*}} i32 @_Z20use_base_via_pointerP7Derived
-// LLVM: %[[D_A_ADDR:.*]] = getelementptr %class.Base, ptr %{{.*}}, i32 0, i32 0
+// LLVM: %[[D_A_ADDR:.*]] = getelementptr inbounds nuw %class.Base, ptr %{{.*}}, i32 0, i32 0
// OGCG: define{{.*}} i32 @_Z20use_base_via_pointerP7Derived
// OGCG: %[[D_A_ADDR:.*]] = getelementptr inbounds nuw %class.Base, ptr %{{.*}}, i32 0, i32 0
diff --git a/clang/test/CIR/CodeGen/complex.cpp b/clang/test/CIR/CodeGen/complex.cpp
index f65f0eea7fbaa..a5427dfa02ef7 100644
--- a/clang/test/CIR/CodeGen/complex.cpp
+++ b/clang/test/CIR/CodeGen/complex.cpp
@@ -816,7 +816,7 @@ void foo31() {
// LLVM: %[[W_ADDR:.*]] = alloca %struct.Wrapper, i64 1, align 4
// LLVM: %[[REAL_ADDR:.*]] = alloca i32, i64 1, align 4
-// LLVM: %[[ELEM_PTR:.*]] = getelementptr %struct.Wrapper, ptr %[[W_ADDR]], i32 0, i32 0
+// LLVM: %[[ELEM_PTR:.*]] = getelementptr inbounds nuw %struct.Wrapper, ptr %[[W_ADDR]], i32 0, i32 0
// LLVM: %[[TMP_ELEM_PTR:.*]] = load { i32, i32 }, ptr %[[ELEM_PTR]], align 4
// LLVM: %[[REAL:.*]] = extractvalue { i32, i32 } %[[TMP_ELEM_PTR]], 0
// LLVM: store i32 %[[REAL]], ptr %[[REAL_ADDR]], align 4
diff --git a/clang/test/CIR/CodeGen/copy-constructor.cpp b/clang/test/CIR/CodeGen/copy-constructor.cpp
index c40cc40741d4e..4d0e5d8933cc1 100644
--- a/clang/test/CIR/CodeGen/copy-constructor.cpp
+++ b/clang/test/CIR/CodeGen/copy-constructor.cpp
@@ -31,9 +31,9 @@ HasScalarArrayMember::HasScalarArrayMember(const HasScalarArrayMember &) = defau
// LLVM-NEXT: store ptr %[[ARG0]], ptr %[[THIS]]
// LLVM-NEXT: store ptr %[[ARG1]], ptr %[[OTHER]]
// LLVM-NEXT: %[[THIS_LOAD:.*]] = load ptr, ptr %[[THIS]]
-// LLVM-NEXT: %[[THIS_ARR:.*]] = getelementptr %struct.HasScalarArrayMember, ptr %[[THIS_LOAD]], i32 0, i32 0
+// LLVM-NEXT: %[[THIS_ARR:.*]] = getelementptr inbounds nuw %struct.HasScalarArrayMember, ptr %[[THIS_LOAD]], i32 0, i32 0
// LLVM-NEXT: %[[OTHER_LOAD:.*]] = load ptr, ptr %[[OTHER]]
-// LLVM-NEXT: %[[OTHER_ARR:.*]] = getelementptr %struct.HasScalarArrayMember, ptr %[[OTHER_LOAD]], i32 0, i32 0
+// LLVM-NEXT: %[[OTHER_ARR:.*]] = getelementptr inbounds nuw %struct.HasScalarArrayMember, ptr %[[OTHER_LOAD]], i32 0, i32 0
// LLVM-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr %[[THIS_ARR]], ptr %[[OTHER_ARR]], i64 16, i1 false)
// LLVM-NEXT: ret void
diff --git a/clang/test/CIR/CodeGen/cxx-default-init.cpp b/clang/test/CIR/CodeGen/cxx-default-init.cpp
index 706eabe01eb21..114bf47f3223b 100644
--- a/clang/test/CIR/CodeGen/cxx-default-init.cpp
+++ b/clang/test/CIR/CodeGen/cxx-default-init.cpp
@@ -61,14 +61,14 @@ struct ZeroInit {
// LLVM: %[[THIS_ALLOCA:.*]] = alloca ptr
// LLVM: %[[ITER:.*]] = alloca ptr
// LLVM: %[[THIS:.*]] = load ptr, ptr %[[THIS_ALLOCA]]
-// LLVM: %[[I:.*]] = getelementptr %struct.ZeroInit, ptr %[[THIS]], i32 0, i32 0
+// LLVM: %[[I:.*]] = getelementptr inbounds nuw %struct.ZeroInit, ptr %[[THIS]], i32 0, i32 0
// LLVM: store i32 0, ptr %[[I]]
-// LLVM: %[[P:.*]] = getelementptr %struct.ZeroInit, ptr %[[THIS]], i32 0, i32 1
-// LLVM: %[[P_A:.*]] = getelementptr %struct.Pair, ptr %[[P]], i32 0, i32 0
+// LLVM: %[[P:.*]] = getelementptr inbounds nuw %struct.ZeroInit, ptr %[[THIS]], i32 0, i32 1
+// LLVM: %[[P_A:.*]] = getelementptr inbounds nuw %struct.Pair, ptr %[[P]], i32 0, i32 0
// LLVM: store i32 0, ptr %[[P_A]]
-// LLVM: %[[P_B:.*]] = getelementptr %struct.Pair, ptr %[[P]], i32 0, i32 1
+// LLVM: %[[P_B:.*]] = getelementptr inbounds nuw %struct.Pair, ptr %[[P]], i32 0, i32 1
// LLVM: store i32 0, ptr %[[P_B]]
-// LLVM: %[[ARR:.*]] = getelementptr %struct.ZeroInit, ptr %[[THIS]], i32 0, i32 2
+// LLVM: %[[ARR:.*]] = getelementptr inbounds nuw %struct.ZeroInit, ptr %[[THIS]], i32 0, i32 2
// LLVM: %[[ARR_BEGIN:.*]] = getelementptr i32, ptr %[[ARR]], i32 0
// LLVM: store ptr %[[ARR_BEGIN]], ptr %[[ITER]]
// LLVM: %[[ARR_END:.*]] = getelementptr i32, ptr %[[ARR_BEGIN]], i64 4
@@ -84,9 +84,9 @@ struct ZeroInit {
// LLVM: store ptr %[[NEXT]], ptr %[[ITER]]
// LLVM: br label %[[LOOP_COND]]
// LLVM: [[LOOP_END]]:
-// LLVM: %[[C:.*]] = getelementptr %struct.ZeroInit, ptr %[[THIS]], i32 0, i32 3
+// LLVM: %[[C:.*]] = getelementptr inbounds nuw %struct.ZeroInit, ptr %[[THIS]], i32 0, i32 3
// LLVM: store { float, float } zeroinitializer, ptr %[[C]]
-// LLVM: %[[BF:.*]] = getelementptr %struct.ZeroInit, ptr %[[THIS]], i32 0, i32 4
+// LLVM: %[[BF:.*]] = getelementptr inbounds nuw %struct.ZeroInit, ptr %[[THIS]], i32 0, i32 4
// LLVM: store i8 0, ptr %[[BF]]
// OGCG: define{{.*}} void @_ZN8ZeroInitC2Ev(ptr {{.*}} %[[THIS_ARG:.*]])
@@ -175,14 +175,14 @@ struct ValueInit {
// LLVM: %[[THIS_ALLOCA:.*]] = alloca ptr
// LLVM: %[[ITER:.*]] = alloca ptr
// LLVM: %[[THIS:.*]] = load ptr, ptr %[[THIS_ALLOCA]]
-// LLVM: %[[I:.*]] = getelementptr %struct.ValueInit, ptr %[[THIS]], i32 0, i32 0
+// LLVM: %[[I:.*]] = getelementptr inbounds nuw %struct.ValueInit, ptr %[[THIS]], i32 0, i32 0
// LLVM: store i32 1, ptr %[[I]]
-// LLVM: %[[P:.*]] = getelementptr %struct.ValueInit, ptr %[[THIS]], i32 0, i32 1
-// LLVM: %[[P_A:.*]] = getelementptr %struct.Pair, ptr %[[P]], i32 0, i32 0
+// LLVM: %[[P:.*]] = getelementptr inbounds nuw %struct.ValueInit, ptr %[[THIS]], i32 0, i32 1
+// LLVM: %[[P_A:.*]] = getelementptr inbounds nuw %struct.Pair, ptr %[[P]], i32 0, i32 0
// LLVM: store i32 2, ptr %[[P_A]]
-// LLVM: %[[P_B:.*]] = getelementptr %struct.Pair, ptr %[[P]], i32 0, i32 1
+// LLVM: %[[P_B:.*]] = getelementptr inbounds nuw %struct.Pair, ptr %[[P]], i32 0, i32 1
// LLVM: store i32 3, ptr %[[P_B]]
-// LLVM: %[[ARR:.*]] = getelementptr %struct.ValueInit, ptr %[[THIS]], i32 0, i32 2
+// LLVM: %[[ARR:.*]] = getelementptr inbounds nuw %struct.ValueInit, ptr %[[THIS]], i32 0, i32 2
// LLVM: %[[ARR_BEGIN:.*]] = getelementptr i32, ptr %[[ARR]], i32 0
// LLVM: store i32 4, ptr %[[ARR_BEGIN]]
// LLVM: %[[ARR_1:.*]] = getelementptr i32, ptr %[[ARR_BEGIN]], i64 1
@@ -202,9 +202,9 @@ struct ValueInit {
// LLVM: store ptr %[[NEXT]], ptr %[[ITER]]
// LLVM: br label %[[LOOP_COND]]
// LLVM: [[LOOP_END]]:
-// LLVM: %[[C:.*]] = getelementptr %struct.ValueInit, ptr %[[THIS]], i32 0, i32 3
+// LLVM: %[[C:.*]] = getelementptr inbounds nuw %struct.ValueInit, ptr %[[THIS]], i32 0, i32 3
// LLVM: store { float, float } { float 6.000000e+00, float 7.000000e+00 }, ptr %[[C]]
-// LLVM: %[[BF:.*]] = getelementptr %struct.ValueInit, ptr %[[THIS]], i32 0, i32 4
+// LLVM: %[[BF:.*]] = getelementptr inbounds nuw %struct.ValueInit, ptr %[[THIS]], i32 0, i32 4
// LLVM: store i8 -1, ptr %[[BF]]
// OGCG: define{{.*}} void @_ZN9ValueInitC2Ev(ptr {{.*}} %[[THIS_ARG:.*]])
diff --git a/clang/test/CIR/CodeGen/delete.cpp b/clang/test/CIR/CodeGen/delete.cpp
index a2fb59cfec2ba..2fb0a936cf305 100644
--- a/clang/test/CIR/CodeGen/delete.cpp
+++ b/clang/test/CIR/CodeGen/delete.cpp
@@ -100,7 +100,7 @@ Container::~Container() { delete contents; }
// LLVM: define dso_local void @_ZN9ContainerD2Ev
// LLVM: %[[THIS:.*]] = load ptr, ptr %{{.*}}
-// LLVM: %[[CONTENTS_PTR_ADDR:.*]] = getelementptr %struct.Container, ptr %[[THIS]], i32 0, i32 0
+// LLVM: %[[CONTENTS_PTR_ADDR:.*]] = getelementptr inbounds nuw %struct.Container, ptr %[[THIS]], i32 0, i32 0
// LLVM: %[[CONTENTS_PTR:.*]] = load ptr, ptr %[[CONTENTS_PTR_ADDR]]
// LLVM: %[[NOT_NULL:.*]] = icmp ne ptr %[[CONTENTS_PTR]], null
// LLVM: br i1 %[[NOT_NULL]], label %[[DELETE_NOTNULL:.*]], label %[[DELETE_END:.*]]
diff --git a/clang/test/CIR/CodeGen/dtors.cpp b/clang/test/CIR/CodeGen/dtors.cpp
index 0e84f4dd6da66..49ec741ad0e11 100644
--- a/clang/test/CIR/CodeGen/dtors.cpp
+++ b/clang/test/CIR/CodeGen/dtors.cpp
@@ -268,7 +268,7 @@ struct D {
// CIR: cir.call @_ZN1CD1Ev(%[[C]])
// LLVM: define {{.*}} void @_ZN1DD2Ev
-// LLVM: %[[C:.*]] = getelementptr %struct.D, ptr %{{.*}}, i32 0, i32 1
+// LLVM: %[[C:.*]] = getelementptr inbounds nuw %struct.D, ptr %{{.*}}, i32 0, i32 1
// LLVM: call void @_ZN1CD1Ev(ptr {{.*}} %[[C]])
// This destructor is defined after the calling function in OGCG.
diff --git a/clang/test/CIR/CodeGen/inline-asm.c b/clang/test/CIR/CodeGen/inline-asm.c
index 55570e1e05550..719b645310918 100644
--- a/clang/test/CIR/CodeGen/inline-asm.c
+++ b/clang/test/CIR/CodeGen/inline-asm.c
@@ -623,9 +623,9 @@ void t17(void) {
//
// Because we go through get_member, the codegen here is slightly different.
// CIRLLVMONLY: store { i32, i32 } %[[ASM_RES]], ptr %[[ASM_RES_VAR]]
-// CIRLLVMONLY: %[[GEP_FIRST:.*]] = getelementptr { i32, i32 }, ptr %[[ASM_RES_VAR]], i32 0, i32 0
+// CIRLLVMONLY: %[[GEP_FIRST:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[ASM_RES_VAR]], i32 0, i32 0
// CIRLLVMONLY: %[[GEP_FIRST_LOAD:.*]] = load i32, ptr %[[GEP_FIRST]]
-// CIRLLVMONLY: %[[GEP_SECOND:.*]] = getelementptr { i32, i32 }, ptr %[[ASM_RES_VAR]], i32 0, i32 1
+// CIRLLVMONLY: %[[GEP_SECOND:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[ASM_RES_VAR]], i32 0, i32 1
// CIRLLVMONLY: %[[GEP_SECOND_LOAD:.*]] = load i32, ptr %[[GEP_SECOND]]
//
// LLVMONLY: %[[GEP_FIRST_LOAD:.*]] = extractvalue { i32, i32 } %[[ASM_RES]], 0
diff --git a/clang/test/CIR/CodeGen/inline-cxx-func.cpp b/clang/test/CIR/CodeGen/inline-cxx-func.cpp
index 38cdf09594ddc..308d78178acf1 100644
--- a/clang/test/CIR/CodeGen/inline-cxx-func.cpp
+++ b/clang/test/CIR/CodeGen/inline-cxx-func.cpp
@@ -33,7 +33,7 @@ struct S {
// LLVM: %[[RET_ADDR:.*]] = alloca i32, i64 1, align 4
// LLVM: store ptr %[[ARG0]], ptr %[[THIS_ADDR]], align 8
// LLVM: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]], align 8
-// LLVM: %[[MEMBER_ADDR:.*]] = getelementptr %struct.S, ptr %[[THIS]], i32 0, i32 0
+// LLVM: %[[MEMBER_ADDR:.*]] = getelementptr inbounds nuw %struct.S, ptr %[[THIS]], i32 0, i32 0
// LLVM: %[[MEMBER:.*]] = load i32, ptr %[[MEMBER_ADDR]], align 4
// LLVM: store i32 %[[MEMBER]], ptr %[[RET_ADDR]], align 4
// LLVM: %[[RET_VAL:.*]] = load i32, ptr %[[RET_ADDR]], align 4
diff --git a/clang/test/CIR/CodeGen/instantiate-init.cpp b/clang/test/CIR/CodeGen/instantiate-init.cpp
index b7f25eb9fd1ec..30e1c7c3a1ee1 100644
--- a/clang/test/CIR/CodeGen/instantiate-init.cpp
+++ b/clang/test/CIR/CodeGen/instantiate-init.cpp
@@ -66,9 +66,9 @@ void init_vec_using_initalizer_list() {
// LLVM: store i32 1, ptr %[[ELEM_1_PTR]], align 4
// LLVM: %[[ELEM_2_PTR:.*]] = getelementptr i32, ptr %[[INIT_LIST_PTR]], i64 2
// LLVM: store i32 2, ptr %[[ELEM_2_PTR]], align 4
-// LLVM: %[[DATA_PTR:.*]] = getelementptr %"class.std::initializer_list<int>", ptr %[[AGG_ADDR]], i32 0, i32 0
+// LLVM: %[[DATA_PTR:.*]] = getelementptr inbounds nuw %"class.std::initializer_list<int>", ptr %[[AGG_ADDR]], i32 0, i32 0
// LLVM: store ptr %[[INIT_LIST_ADDR]], ptr %[[DATA_PTR]], align 8
-// LLVM: %[[SIZE_PTR:.*]] = getelementptr %"class.std::initializer_list<int>", ptr %[[AGG_ADDR]], i32 0, i32 1
+// LLVM: %[[SIZE_PTR:.*]] = getelementptr inbounds nuw %"class.std::initializer_list<int>", ptr %[[AGG_ADDR]], i32 0, i32 1
// LLVM: store i64 3, ptr %[[SIZE_PTR]], align 8
// LLVM: %[[TMP_AGG:.*]] = load %"class.std::initializer_list<int>", ptr %[[AGG_ADDR]], align 8
// LLVM: call void @_ZN6VectorC1ESt16initializer_listIiE(ptr noundef nonnull align 1 dereferenceable(1) %[[VEC_ADDR]], %"class.std::initializer_list<int>" %[[TMP_AGG]])
diff --git a/clang/test/CIR/CodeGen/lambda.cpp b/clang/test/CIR/CodeGen/lambda.cpp
index 6dc5e16d79e98..7a15f4fb289e8 100644
--- a/clang/test/CIR/CodeGen/lambda.cpp
+++ b/clang/test/CIR/CodeGen/lambda.cpp
@@ -111,11 +111,11 @@ void l0() {
// LLVM: %[[THIS_ADDR:.*]] = alloca ptr
// LLVM: store ptr %[[THIS_ARG]], ptr %[[THIS_ADDR]]
// LLVM: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]
-// LLVM: %[[I_ADDR_ADDR:.*]] = getelementptr %[[REC_LAM_L0_A:.*]], ptr %[[THIS]], i32 0, i32 0
+// LLVM: %[[I_ADDR_ADDR:.*]] = getelementptr inbounds nuw %[[REC_LAM_L0_A:.*]], ptr %[[THIS]], i32 0, i32 0
// LLVM: %[[I_ADDR:.*]] = load ptr, ptr %[[I_ADDR_ADDR]]
// LLVM: %[[I:.*]] = load i32, ptr %[[I_ADDR]]
// LLVM: %[[ADD:.*]] = add nsw i32 %[[I]], 1
-// LLVM: %[[I_ADDR_ADDR:.*]] = getelementptr %[[REC_LAM_L0_A]], ptr %[[THIS]], i32 0, i32 0
+// LLVM: %[[I_ADDR_ADDR:.*]] = getelementptr inbounds nuw %[[REC_LAM_L0_A]], ptr %[[THIS]], i32 0, i32 0
// LLVM: %[[I_ADDR:.*]] = load ptr, ptr %[[I_ADDR_ADDR]]
// LLVM: store i32 %[[ADD]], ptr %[[I_ADDR]]
// LLVM: ret void
@@ -123,7 +123,7 @@ void l0() {
// LLVM: define {{.*}} void @_Z2l0v()
// LLVM: %[[I:.*]] = alloca i32
// LLVM: %[[A:.*]] = alloca %[[REC_LAM_L0_A]]
-// LLVM: %[[I_ADDR:.*]] = getelementptr %[[REC_LAM_L0_A]], ptr %[[A]], i32 0, i32 0
+// LLVM: %[[I_ADDR:.*]] = getelementptr inbounds nuw %[[REC_LAM_L0_A]], ptr %[[A]], i32 0, i32 0
// LLVM: store ptr %[[I]], ptr %[[I_ADDR]]
// LLVM: call void @"_ZZ2l0vENK3$_0clEv"(ptr {{.*}} %[[A]])
// LLVM: ret void
@@ -174,7 +174,7 @@ auto g() {
// LLVM: %[[RETVAL:.*]] = alloca %[[REC_LAM_G]]
// LLVM: %[[I:.*]] = alloca i32
// LLVM: store i32 12, ptr %[[I]]
-// LLVM: %[[I_ADDR:.*]] = getelementptr %[[REC_LAM_G]], ptr %[[RETVAL]], i32 0, i32 0
+// LLVM: %[[I_ADDR:.*]] = getelementptr inbounds nuw %[[REC_LAM_G]], ptr %[[RETVAL]], i32 0, i32 0
// LLVM: store ptr %[[I]], ptr %[[I_ADDR]]
// LLVM: %[[RET:.*]] = load %[[REC_LAM_G]], ptr %[[RETVAL]]
// LLVM: ret %[[REC_LAM_G]] %[[RET]]
@@ -213,7 +213,7 @@ auto g2() {
// LLVM: %[[RETVAL:.*]] = alloca %[[REC_LAM_G]]
// LLVM: %[[I:.*]] = alloca i32
// LLVM: store i32 12, ptr %[[I]]
-// LLVM: %[[I_ADDR:.*]] = getelementptr %[[REC_LAM_G]], ptr %[[RETVAL]], i32 0, i32 0
+// LLVM: %[[I_ADDR:.*]] = getelementptr inbounds nuw %[[REC_LAM_G]], ptr %[[RETVAL]], i32 0, i32 0
// LLVM: store ptr %[[I]], ptr %[[I_ADDR]]
// LLVM: %[[RET:.*]] = load %[[REC_LAM_G]], ptr %[[RETVAL]]
// LLVM: ret %[[REC_LAM_G]] %[[RET]]
@@ -267,12 +267,12 @@ int f() {
// LLVM: %[[I_ALLOCA:.*]] = alloca i32
// LLVM: store ptr %[[THIS_ARG]], ptr %[[THIS_ALLOCA]]
// LLVM: %[[THIS:.*]] = load ptr, ptr %[[THIS_ALLOCA]]
-// LLVM: %[[I_ADDR_ADDR:.*]] = getelementptr %[[REC_LAM_G2:.*]], ptr %[[THIS]], i32 0, i32 0
+// LLVM: %[[I_ADDR_ADDR:.*]] = getelementptr inbounds nuw %[[REC_LAM_G2:.*]], ptr %[[THIS]], i32 0, i32 0
// LLVM: %[[I_ADDR:.*]] = load ptr, ptr %[[I_ADDR_ADDR]]
// LLVM: %[[I:.*]] = load i32, ptr %[[I_ADDR]]
// LLVM: %[[ADD:.*]] = add nsw i32 %[[I]], 100
// LLVM: store i32 %[[ADD]], ptr %[[I_ADDR]]
-// LLVM: %[[I_ADDR_ADDR:.*]] = getelementptr %[[REC_LAM_G2]], ptr %[[THIS]], i32 0, i32 0
+// LLVM: %[[I_ADDR_ADDR:.*]] = getelementptr inbounds nuw %[[REC_LAM_G2]], ptr %[[THIS]], i32 0, i32 0
// LLVM: %[[I_ADDR:.*]] = load ptr, ptr %[[I_ADDR_ADDR]]
// LLVM: %[[I:.*]] = load i32, ptr %[[I_ADDR]]
// LLVM: store i32 %[[I]], ptr %[[I_ALLOCA]]
@@ -349,8 +349,8 @@ struct A {
// LLVM: %[[RETVAL:.*]] = alloca i32
// LLVM: store ptr %[[THIS_ARG]], ptr %[[THIS_ALLOCA]]
// LLVM: %[[THIS:.*]] = load ptr, ptr %[[THIS_ALLOCA]]
-// LLVM: %[[PTR_A:.*]] = getelementptr %[[REC_LAM_A:.*]], ptr %[[THIS]], i32 0, i32 0
-// LLVM: %[[A_A_ADDR:.*]] = getelementptr %struct.A, ptr %[[PTR_A]], i32 0, i32 0
+// LLVM: %[[PTR_A:.*]] = getelementptr inbounds nuw %[[REC_LAM_A:.*]], ptr %[[THIS]], i32 0, i32 0
+// LLVM: %[[A_A_ADDR:.*]] = getelementptr inbounds nuw %struct.A, ptr %[[PTR_A]], i32 0, i32 0
// LLVM: %[[A_A:.*]] = load i32, ptr %[[A_A_ADDR]]
// LLVM: store i32 %[[A_A]], ptr %[[RETVAL]]
// LLVM: %[[RET:.*]] = load i32, ptr %[[RETVAL]]
@@ -382,7 +382,7 @@ struct A {
// LLVM: %[[THIS:.*]] = load ptr, ptr %[[THIS_ALLOCA]]
// LLVM: br label %[[SCOPE_BB:.*]]
// LLVM: [[SCOPE_BB]]:
-// LLVM: %[[STRUCT_A:.*]] = getelementptr %[[REC_LAM_A]], ptr %[[LAM_ALLOCA]], i32 0, i32 0
+// LLVM: %[[STRUCT_A:.*]] = getelementptr inbounds nuw %[[REC_LAM_A]], ptr %[[LAM_ALLOCA]], i32 0, i32 0
// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %[[STRUCT_A]], ptr %[[THIS]], i64 4, i1 false)
// LLVM: %[[LAM_RET:.*]] = call noundef i32 @_ZZN1A3fooEvENKUlvE_clEv(ptr {{.*}} %[[LAM_ALLOCA]])
// LLVM: store i32 %[[LAM_RET]], ptr %[[RETVAL]]
@@ -420,9 +420,9 @@ struct A {
// LLVM: %[[RETVAL:.*]] = alloca i32
// LLVM: store ptr %[[THIS_ARG]], ptr %[[THIS_ALLOCA]]
// LLVM: %[[THIS:.*]] = load ptr, ptr %[[THIS_ALLOCA]]
-// LLVM: %[[STRUCT_A_ADDRR_ADDR:.*]] = getelementptr %[[REC_LAM_PTR_A:.*]], ptr %[[THIS]], i32 0, i32 0
+// LLVM: %[[STRUCT_A_ADDRR_ADDR:.*]] = getelementptr inbounds nuw %[[REC_LAM_PTR_A:.*]], ptr %[[THIS]], i32 0, i32 0
// LLVM: %[[STRUCT_A_ADDR:.*]] = load ptr, ptr %[[STRUCT_A_ADDRR_ADDR]]
-// LLVM: %[[A_A_ADDR:.*]] = getelementptr %struct.A, ptr %[[STRUCT_A_ADDR]], i32 0, i32 0
+// LLVM: %[[A_A_ADDR:.*]] = getelementptr inbounds nuw %struct.A, ptr %[[STRUCT_A_ADDR]], i32 0, i32 0
// LLVM: %[[A_A:.*]] = load i32, ptr %[[A_A_ADDR]]
// LLVM: store i32 %[[A_A]], ptr %[[RETVAL]]
// LLVM: %[[RET:.*]] = load i32, ptr %[[RETVAL]]
@@ -454,7 +454,7 @@ struct A {
// LLVM: %[[THIS:.*]] = load ptr, ptr %[[THIS_ALLOCA]]
// LLVM: br label %[[SCOPE_BB:.*]]
// LLVM: [[SCOPE_BB]]:
-// LLVM: %[[A_ADDR_ADDR:.*]] = getelementptr %[[REC_LAM_PTR_A]], ptr %[[LAM_ALLOCA]], i32 0, i32 0
+// LLVM: %[[A_ADDR_ADDR:.*]] = getelementptr inbounds nuw %[[REC_LAM_PTR_A]], ptr %[[LAM_ALLOCA]], i32 0, i32 0
// LLVM: store ptr %[[THIS]], ptr %[[A_ADDR_ADDR]]
// LLVM: %[[LAM_RET:.*]] = call noundef i32 @_ZZN1A3barEvENKUlvE_clEv(ptr {{.*}} %[[LAM_ALLOCA]])
// LLVM: store i32 %[[LAM_RET]], ptr %[[RETVAL]]
diff --git a/clang/test/CIR/CodeGen/no-unique-address.cpp b/clang/test/CIR/CodeGen/no-unique-address.cpp
index 41aa6388c1e8a..46ff978bb63ff 100644
--- a/clang/test/CIR/CodeGen/no-unique-address.cpp
+++ b/clang/test/CIR/CodeGen/no-unique-address.cpp
@@ -42,7 +42,7 @@ struct Outer {
// CIR: %[[EXTRA:.*]] = cir.get_member %[[THIS]][1] {name = "extra"} : !cir.ptr<!rec_Outer> -> !cir.ptr<!s8i>
// LLVM-LABEL: define {{.*}} void @_ZN5OuterC2ERK6Middlec(
-// LLVM: %[[GEP:.*]] = getelementptr %struct.Outer, ptr %{{.+}}, i32 0, i32 0
+// LLVM: %[[GEP:.*]] = getelementptr inbounds nuw %struct.Outer, ptr %{{.+}}, i32 0, i32 0
// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %[[GEP]], ptr %{{.+}}, i64 5, i1 false)
// OGCG-LABEL: define {{.*}} void @_ZN5OuterC2ERK6Middlec(
diff --git a/clang/test/CIR/CodeGen/statement-exprs.c b/clang/test/CIR/CodeGen/statement-exprs.c
index 30baaf0ec8736..42c8c2c3d2528 100644
--- a/clang/test/CIR/CodeGen/statement-exprs.c
+++ b/clang/test/CIR/CodeGen/statement-exprs.c
@@ -259,7 +259,7 @@ int test3() { return ({ struct S s = {1}; s; }).x; }
// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %[[VAR1]], ptr %[[VAR3]], i64 4, i1 false)
// LLVM: br label %[[LBL8:.+]]
// LLVM: [[LBL8]]:
-// LLVM: %[[GEP_VAR1:.+]] = getelementptr %struct.S, ptr %[[VAR1]], i32 0, i32 0
+// LLVM: %[[GEP_VAR1:.+]] = getelementptr inbounds nuw %struct.S, ptr %[[VAR1]], i32 0, i32 0
// LLVM: %[[LOAD_X:.+]] = load i32, ptr %[[GEP_VAR1]]
// LLVM: store i32 %[[LOAD_X]], ptr %[[VAR4]]
// LLVM: br label %[[LBL11:.+]]
diff --git a/clang/test/CIR/CodeGen/struct-init.cpp b/clang/test/CIR/CodeGen/struct-init.cpp
index 3f23b9868c844..ee9321cdc042f 100644
--- a/clang/test/CIR/CodeGen/struct-init.cpp
+++ b/clang/test/CIR/CodeGen/struct-init.cpp
@@ -112,10 +112,10 @@ void init_var(int a, int b) {
// LLVM: %[[S:.*]] = alloca %struct.S
// LLVM: store i32 %[[A_ARG]], ptr %[[A_PTR]]
// LLVM: store i32 %[[B_ARG]], ptr %[[B_PTR]]
-// LLVM: %[[S_A:.*]] = getelementptr %struct.S, ptr %[[S]], i32 0, i32 0
+// LLVM: %[[S_A:.*]] = getelementptr inbounds nuw %struct.S, ptr %[[S]], i32 0, i32 0
// LLVM: %[[A:.*]] = load i32, ptr %[[A_PTR]]
// LLVM: store i32 %[[A]], ptr %[[S_A]]
-// LLVM: %[[S_B:.*]] = getelementptr %struct.S, ptr %[[S]], i32 0, i32 1
+// LLVM: %[[S_B:.*]] = getelementptr inbounds nuw %struct.S, ptr %[[S]], i32 0, i32 1
// LLVM: %[[B:.*]] = load i32, ptr %[[B_PTR]]
// LLVM: store i32 %[[B]], ptr %[[S_B]]
// LLVM: ret void
@@ -173,15 +173,15 @@ void init_expr(int a, int b, int c) {
// LLVM: store i32 %[[A_ARG]], ptr %[[A_PTR]]
// LLVM: store i32 %[[B_ARG]], ptr %[[B_PTR]]
// LLVM: store i32 %[[C_ARG]], ptr %[[C_PTR]]
-// LLVM: %[[S_A:.*]] = getelementptr %struct.S, ptr %[[S]], i32 0, i32 0
+// LLVM: %[[S_A:.*]] = getelementptr inbounds nuw %struct.S, ptr %[[S]], i32 0, i32 0
// LLVM: %[[A:.*]] = load i32, ptr %[[A_PTR]]
// LLVM: %[[A_PLUS_ONE:.*]] = add nsw i32 %[[A]], 1
// LLVM: store i32 %[[A_PLUS_ONE]], ptr %[[S_A]]
-// LLVM: %[[S_B:.*]] = getelementptr %struct.S, ptr %[[S]], i32 0, i32 1
+// LLVM: %[[S_B:.*]] = getelementptr inbounds nuw %struct.S, ptr %[[S]], i32 0, i32 1
// LLVM: %[[B:.*]] = load i32, ptr %[[B_PTR]]
// LLVM: %[[B_PLUS_TWO:.*]] = add nsw i32 %[[B]], 2
// LLVM: store i32 %[[B_PLUS_TWO]], ptr %[[S_B]]
-// LLVM: %[[S_C:.*]] = getelementptr %struct.S, ptr %[[S]], i32 0, i32 2
+// LLVM: %[[S_C:.*]] = getelementptr inbounds nuw %struct.S, ptr %[[S]], i32 0, i32 2
// LLVM: %[[C:.*]] = load i32, ptr %[[C_PTR]]
// LLVM: %[[C_PLUS_THREE:.*]] = add nsw i32 %[[C]], 3
// LLVM: store i32 %[[C_PLUS_THREE]], ptr %[[S_C]]
@@ -223,7 +223,7 @@ void cxx_default_init_with_struct_field() {
// CIR: cir.store{{.*}} %[[METHOD_CALL]], %[[P_ELEM_0_PTR]] : !s32i, !cir.ptr<!s32i>
// LLVM: %[[P_ADDR:.*]] = alloca %struct.Parent, i64 1, align 4
-// LLVM: %[[P_ELEM_0_PTR:.*]] = getelementptr %struct.Parent, ptr %[[P_ADDR]], i32 0, i32 0
+// LLVM: %[[P_ELEM_0_PTR:.*]] = getelementptr inbounds nuw %struct.Parent, ptr %[[P_ADDR]], i32 0, i32 0
// LLVM: %[[METHOD_CALL:.*]] = call noundef i32 @_ZZ34cxx_default_init_with_struct_fieldvEN6Parent4getAEv(ptr {{.*}} %[[P_ADDR]])
// LLVM: store i32 %[[METHOD_CALL]], ptr %[[P_ELEM_0_PTR]], align 4
diff --git a/clang/test/CIR/CodeGen/struct.c b/clang/test/CIR/CodeGen/struct.c
index 0aeec4ac7e292..60448099cff1f 100644
--- a/clang/test/CIR/CodeGen/struct.c
+++ b/clang/test/CIR/CodeGen/struct.c
@@ -266,10 +266,10 @@ char f4(int a, struct CompleteS *p) {
// LLVM-NEXT: store ptr %[[ARG_P]], ptr %[[P_ADDR]], align 8
// LLVM-NEXT: %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4
// LLVM-NEXT: %[[P_VAL:.*]] = load ptr, ptr %[[P_ADDR]], align 8
-// LLVM-NEXT: %[[P_A:.*]] = getelementptr %struct.CompleteS, ptr %[[P_VAL]], i32 0, i32 0
+// LLVM-NEXT: %[[P_A:.*]] = getelementptr inbounds nuw %struct.CompleteS, ptr %[[P_VAL]], i32 0, i32 0
// LLVM-NEXT: store i32 %[[A_VAL]], ptr %[[P_A]], align 4
// LLVM-NEXT: %[[P_VAL2:.*]] = load ptr, ptr %[[P_ADDR]], align 8
-// LLVM-NEXT: %[[P_B:.*]] = getelementptr %struct.CompleteS, ptr %[[P_VAL2]], i32 0, i32 1
+// LLVM-NEXT: %[[P_B:.*]] = getelementptr inbounds nuw %struct.CompleteS, ptr %[[P_VAL2]], i32 0, i32 1
// LLVM-NEXT: %[[P_B_VAL:.*]] = load i8, ptr %[[P_B]], align 4
// LLVM-NEXT: store i8 %[[P_B_VAL]], ptr %[[RETVAL_ADDR]], align 1
// LLVM-NEXT: %[[RETVAL:.*]] = load i8, ptr %[[RETVAL_ADDR]], align 1
@@ -299,7 +299,7 @@ void f5(struct NodeS* a) {
// CIR: cir.store {{.*}}, %[[NEXT]]
// LLVM: define{{.*}} void @f5
-// LLVM: %[[NEXT:.*]] = getelementptr %struct.NodeS, ptr %{{.*}}, i32 0, i32 0
+// LLVM: %[[NEXT:.*]] = getelementptr inbounds nuw %struct.NodeS, ptr %{{.*}}, i32 0, i32 0
// LLVM: store ptr null, ptr %[[NEXT]]
// OGCG: define{{.*}} void @f5
@@ -318,9 +318,9 @@ void f6(struct CycleStart *start) {
// CIR: %[[START2:.*]] = cir.get_member %{{.*}}[0] {name = "start"} : !cir.ptr<!rec_CycleEnd> -> !cir.ptr<!cir.ptr<!rec_CycleStart>>
// LLVM: define{{.*}} void @f6
-// LLVM: %[[MIDDLE:.*]] = getelementptr %struct.CycleStart, ptr %{{.*}}, i32 0, i32 0
-// LLVM: %[[END:.*]] = getelementptr %struct.CycleMiddle, ptr %{{.*}}, i32 0, i32 0
-// LLVM: %[[START2:.*]] = getelementptr %struct.CycleEnd, ptr %{{.*}}, i32 0, i32 0
+// LLVM: %[[MIDDLE:.*]] = getelementptr inbounds nuw %struct.CycleStart, ptr %{{.*}}, i32 0, i32 0
+// LLVM: %[[END:.*]] = getelementptr inbounds nuw %struct.CycleMiddle, ptr %{{.*}}, i32 0, i32 0
+// LLVM: %[[START2:.*]] = getelementptr inbounds nuw %struct.CycleEnd, ptr %{{.*}}, i32 0, i32 0
// OGCG: define{{.*}} void @f6
// OGCG: %[[MIDDLE:.*]] = getelementptr inbounds nuw %struct.CycleStart, ptr %{{.*}}, i32 0, i32 0
diff --git a/clang/test/CIR/CodeGen/struct.cpp b/clang/test/CIR/CodeGen/struct.cpp
index 409145350f693..1c86a856d04a5 100644
--- a/clang/test/CIR/CodeGen/struct.cpp
+++ b/clang/test/CIR/CodeGen/struct.cpp
@@ -64,7 +64,7 @@ char f2(CompleteS &s) {
// LLVM: %[[S_ADDR:.*]] = alloca ptr
// LLVM: store ptr %[[ARG_S]], ptr %[[S_ADDR]]
// LLVM: %[[S_REF:.*]] = load ptr, ptr %[[S_ADDR]], align 8
-// LLVM: %[[S_ADDR2:.*]] = getelementptr %struct.CompleteS, ptr %[[S_REF]], i32 0, i32 1
+// LLVM: %[[S_ADDR2:.*]] = getelementptr inbounds nuw %struct.CompleteS, ptr %[[S_REF]], i32 0, i32 1
// LLVM: %[[S_B:.*]] = load i8, ptr %[[S_ADDR2]]
// OGCG: define{{.*}} i8 @_Z2f2R9CompleteS(ptr{{.*}} %[[ARG_S:.*]])
@@ -95,8 +95,8 @@ void f3() {
// LLVM: define{{.*}} void @_Z2f3v()
// LLVM: %[[O:.*]] = alloca %struct.Outer, i64 1, align 4
-// LLVM: %[[O_I:.*]] = getelementptr %struct.Outer, ptr %[[O]], i32 0, i32 0
-// LLVM: %[[O_I_N:.*]] = getelementptr %struct.Inner, ptr %[[O_I]], i32 0, i32 0
+// LLVM: %[[O_I:.*]] = getelementptr inbounds nuw %struct.Outer, ptr %[[O]], i32 0, i32 0
+// LLVM: %[[O_I_N:.*]] = getelementptr inbounds nuw %struct.Inner, ptr %[[O_I]], i32 0, i32 0
// OGCG: define{{.*}} void @_Z2f3v()
// OGCG: %[[O:.*]] = alloca %struct.Outer, align 4
@@ -203,11 +203,11 @@ void designated_init_update_expr() {
// LLVM: %[[A_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 4
// LLVM: %[[B_ADDR:.*]] = alloca %struct.Container, i64 1, align 4
-// LLVM: %[[C_ADDR:.*]] = getelementptr %struct.Container, ptr %[[B_ADDR]], i32 0, i32 0
+// LLVM: %[[C_ADDR:.*]] = getelementptr inbounds nuw %struct.Container, ptr %[[B_ADDR]], i32 0, i32 0
// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %[[C_ADDR]], ptr %[[A_ADDR]], i64 8, i1 false)
-// LLVM: %[[ELEM_0_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[C_ADDR]], i32 0, i32 0
+// LLVM: %[[ELEM_0_PTR:.*]] = getelementptr inbounds nuw %struct.CompleteS, ptr %[[C_ADDR]], i32 0, i32 0
// LLVM: store i32 1, ptr %[[ELEM_0_PTR]], align 4
-// LLVM: %[[ELEM_1_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[C_ADDR]], i32 0, i32 1
+// LLVM: %[[ELEM_1_PTR:.*]] = getelementptr inbounds nuw %struct.CompleteS, ptr %[[C_ADDR]], i32 0, i32 1
// OGCG: %[[A_ADDR:.*]] = alloca %struct.CompleteS, align 4
// OGCG: %[[B_ADDR:.*]] = alloca %struct.Container, align 4
@@ -233,9 +233,9 @@ void atomic_init() {
// LLVM: define{{.*}} void @_Z11atomic_initv()
// LLVM: %[[A_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 8
-// LLVM: %[[ELEM_0_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[A_ADDR]], i32 0, i32 0
+// LLVM: %[[ELEM_0_PTR:.*]] = getelementptr inbounds nuw %struct.CompleteS, ptr %[[A_ADDR]], i32 0, i32 0
// LLVM: store i32 0, ptr %[[ELEM_0_PTR]], align 8
-// LLVM: %[[ELEM_1_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[A_ADDR]], i32 0, i32 1
+// LLVM: %[[ELEM_1_PTR:.*]] = getelementptr inbounds nuw %struct.CompleteS, ptr %[[A_ADDR]], i32 0, i32 1
// LLVM: store i8 0, ptr %[[ELEM_1_PTR]], align 4
// OGCG: define{{.*}} void @_Z11atomic_initv()
@@ -310,7 +310,7 @@ void struct_with_const_member_expr() {
// LLVM: %[[A_ADDR:.*]] = alloca i32, i64 1, align 4
// LLVM: %[[REF_ADDR:.*]] = alloca %struct.StructWithConstMember, i64 1, align 4
-// LLVM: %[[ELEM_0_PTR:.*]] = getelementptr %struct.StructWithConstMember, ptr %[[REF_ADDR]], i32 0, i32 0
+// LLVM: %[[ELEM_0_PTR:.*]] = getelementptr inbounds nuw %struct.StructWithConstMember, ptr %[[REF_ADDR]], i32 0, i32 0
// LLVM: %[[TMP_REF:.*]] = load i8, ptr %[[ELEM_0_PTR]], align 4
// LLVM: %[[BF_CLEAR:.*]] = and i8 %[[TMP_REF]], -2
// LLVM: %[[BF_SET:.*]] = or i8 %[[BF_CLEAR]], 0
@@ -353,9 +353,9 @@ void calling_function_with_default_values() {
// TODO(CIR): the difference between the CIR LLVM and OGCG is because the lack of calling convention lowering,
// LLVM: %[[AGG_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 4
-// LLVM: %[[ELEM_0_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[AGG_ADDR]], i32 0, i32 0
+// LLVM: %[[ELEM_0_PTR:.*]] = getelementptr inbounds nuw %struct.CompleteS, ptr %[[AGG_ADDR]], i32 0, i32 0
// LLVM: store i32 1, ptr %[[ELEM_0_PTR]], align 4
-// LLVM: %[[ELEM_1_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[AGG_ADDR]], i32 0, i32 1
+// LLVM: %[[ELEM_1_PTR:.*]] = getelementptr inbounds nuw %struct.CompleteS, ptr %[[AGG_ADDR]], i32 0, i32 1
// LLVM: store i8 2, ptr %[[ELEM_1_PTR]], align 4
// LLVM: %[[TMP_AGG:.*]] = load %struct.CompleteS, ptr %[[AGG_ADDR]], align 4
// LLVM: call void @_Z31function_arg_with_default_value9CompleteS(%struct.CompleteS %[[TMP_AGG]])
diff --git a/clang/test/CIR/CodeGen/variable-decomposition.cpp b/clang/test/CIR/CodeGen/variable-decomposition.cpp
index a8a51ab846c18..569f36bf753de 100644
--- a/clang/test/CIR/CodeGen/variable-decomposition.cpp
+++ b/clang/test/CIR/CodeGen/variable-decomposition.cpp
@@ -38,10 +38,10 @@ float function() {
// LLVM: %[[RETVAL:.+]] = alloca float, i64 1
// LLVM: %[[STRUCT:.+]] = alloca %struct.some_struct, i64 1
// LLVM: call void @llvm.memcpy{{.*}}(ptr %[[STRUCT]], ptr @[[FUNC_CONST]], i64 8, i1 false)
-// LLVM: %[[GEP_A:.+]] = getelementptr %struct.some_struct, ptr %[[STRUCT]], i32 0, i32 0
+// LLVM: %[[GEP_A:.+]] = getelementptr inbounds nuw %struct.some_struct, ptr %[[STRUCT]], i32 0, i32 0
// LLVM: %[[LOAD_A:.+]] = load i32, ptr %[[GEP_A]]
// LLVM: %[[CAST_A:.+]] = sitofp i32 %[[LOAD_A]] to float
-// LLVM: %[[GEP_B:.+]] = getelementptr %struct.some_struct, ptr %[[STRUCT]], i32 0, i32 1
+// LLVM: %[[GEP_B:.+]] = getelementptr inbounds nuw %struct.some_struct, ptr %[[STRUCT]], i32 0, i32 1
// LLVM: %[[LOAD_B:.+]] = load float, ptr %[[GEP_B]]
// LLVM: %[[ADD:.+]] = fadd float %[[CAST_A]], %[[LOAD_B]]
// LLVM: store float %[[ADD]], ptr %[[RETVAL]]
diff --git a/clang/test/CIR/CodeGen/volatile.cpp b/clang/test/CIR/CodeGen/volatile.cpp
index 17a7154291692..ffe40aa12a7ba 100644
--- a/clang/test/CIR/CodeGen/volatile.cpp
+++ b/clang/test/CIR/CodeGen/volatile.cpp
@@ -46,7 +46,7 @@ int test_load_field1(volatile Foo *ptr) {
// CIR: %{{.+}} = cir.load volatile{{.*}} %[[MEMBER_ADDR]]
// LLVM: define {{.*}} i32 @_Z16test_load_field1PV3Foo
-// LLVM: %[[MEMBER_ADDR:.*]] = getelementptr %struct.Foo, ptr %{{.*}}, i32 0, i32 0
+// LLVM: %[[MEMBER_ADDR:.*]] = getelementptr inbounds nuw %struct.Foo, ptr %{{.*}}, i32 0, i32 0
// LLVM: %{{.*}} = load volatile i32, ptr %[[MEMBER_ADDR]]
// OGCG: define {{.*}} i32 @_Z16test_load_field1PV3Foo
@@ -62,7 +62,7 @@ int test_load_field2(Foo *ptr) {
// CIR: %{{.+}} = cir.load volatile{{.*}} %[[MEMBER_ADDR]]
// LLVM: define {{.*}} i32 @_Z16test_load_field2P3Foo
-// LLVM: %[[MEMBER_ADDR:.*]] = getelementptr %struct.Foo, ptr %{{.*}}, i32 0, i32 1
+// LLVM: %[[MEMBER_ADDR:.*]] = getelementptr inbounds nuw %struct.Foo, ptr %{{.*}}, i32 0, i32 1
// LLVM: %{{.*}} = load volatile i32, ptr %[[MEMBER_ADDR]]
// OGCG: define {{.*}} i32 @_Z16test_load_field2P3Foo
@@ -78,7 +78,7 @@ int test_load_field3(Foo *ptr) {
// CIR: %{{.*}} = cir.get_bitfield align(4) (#bfi_z, %[[MEMBER_ADDR:.+]] {is_volatile} : !cir.ptr<!u8i>) -> !s32i
// LLVM: define {{.*}} i32 @_Z16test_load_field3P3Foo
-// LLVM: %[[MEMBER_ADDR:.*]] = getelementptr %struct.Foo, ptr %{{.*}}, i32 0, i32 2
+// LLVM: %[[MEMBER_ADDR:.*]] = getelementptr inbounds nuw %struct.Foo, ptr %{{.*}}, i32 0, i32 2
// LLVM: %[[TMP1:.*]] = load volatile i8, ptr %[[MEMBER_ADDR]]
// LLVM: %[[TMP2:.*]] = shl i8 %[[TMP1]], 4
// LLVM: %[[TMP3:.*]] = ashr i8 %[[TMP2]], 4
@@ -100,7 +100,7 @@ void test_store_field1(volatile Foo *ptr) {
// CIR: cir.store volatile{{.*}} %{{.+}}, %[[MEMBER_ADDR]]
// LLVM: define {{.*}} void @_Z17test_store_field1PV3Foo
-// LLVM: %[[MEMBER_ADDR:.*]] = getelementptr %struct.Foo, ptr %{{.*}}, i32 0, i32 0
+// LLVM: %[[MEMBER_ADDR:.*]] = getelementptr inbounds nuw %struct.Foo, ptr %{{.*}}, i32 0, i32 0
// LLVM: store volatile i32 42, ptr %[[MEMBER_ADDR]]
// OGCG: define {{.*}} void @_Z17test_store_field1PV3Foo
@@ -116,7 +116,7 @@ void test_store_field2(Foo *ptr) {
// CIR: cir.store volatile{{.*}} %{{.+}}, %[[MEMBER_ADDR]]
// LLVM: define {{.*}} void @_Z17test_store_field2P3Foo
-// LLVM: %[[MEMBER_ADDR:.*]] = getelementptr %struct.Foo, ptr %{{.*}}, i32 0, i32 1
+// LLVM: %[[MEMBER_ADDR:.*]] = getelementptr inbounds nuw %struct.Foo, ptr %{{.*}}, i32 0, i32 1
// LLVM: store volatile i32 42, ptr %[[MEMBER_ADDR]]
// OGCG: define {{.*}} void @_Z17test_store_field2P3Foo
@@ -132,7 +132,7 @@ void test_store_field3(Foo *ptr) {
// CIR: cir.set_bitfield align(4) (#bfi_z, %[[MEMBER_ADDR:.+]] : !cir.ptr<!u8i>, %1 : !s32i) {is_volatile}
// LLVM: define {{.*}} void @_Z17test_store_field3P3Foo
-// LLVM: %[[MEMBER_ADDR:.*]] = getelementptr %struct.Foo, ptr %{{.*}}, i32 0, i32 2
+// LLVM: %[[MEMBER_ADDR:.*]] = getelementptr inbounds nuw %struct.Foo, ptr %{{.*}}, i32 0, i32 2
// LLVM: %[[TMP1:.*]] = load volatile i8, ptr %[[MEMBER_ADDR]]
// LLVM: %[[TMP2:.*]] = and i8 %[[TMP1]], -16
// LLVM: %[[TMP3:.*]] = or i8 %[[TMP2]], 4
@@ -160,7 +160,7 @@ void A::set_x(int val) volatile {
// CIR: cir.store volatile {{.*}} %{{.*}}, %[[MEMBER_ADDR]]
// LLVM: define {{.*}} void @_ZNV1A5set_xEi
-// LLVM: %[[MEMBER_ADDR:.*]] = getelementptr %struct.A, ptr %{{.*}}, i32 0, i32 0
+// LLVM: %[[MEMBER_ADDR:.*]] = getelementptr inbounds nuw %struct.A, ptr %{{.*}}, i32 0, i32 0
// LLVM: store volatile i32 %{{.*}}, ptr %[[MEMBER_ADDR]]
// OGCG: define {{.*}} void @_ZNV1A5set_xEi
@@ -176,7 +176,7 @@ int A::get_x() volatile {
// CIR: cir.load volatile {{.*}} %[[MEMBER_ADDR]]
// LLVM: define {{.*}} i32 @_ZNV1A5get_xEv
-// LLVM: %[[MEMBER_ADDR:.*]] = getelementptr %struct.A, ptr %{{.*}}, i32 0, i32 0
+// LLVM: %[[MEMBER_ADDR:.*]] = getelementptr inbounds nuw %struct.A, ptr %{{.*}}, i32 0, i32 0
// LLVM: %{{.*}} = load volatile i32, ptr %[[MEMBER_ADDR]]
// OGCG: define {{.*}} i32 @_ZNV1A5get_xEv
More information about the llvm-branch-commits
mailing list