[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