https://github.com/erichkeane updated 
https://github.com/llvm/llvm-project/pull/227899

>From 7feddc151d9dfe89b671a15efafc591c7d6caa96 Mon Sep 17 00:00:00 2001
From: erichkeane <[email protected]>
Date: Wed, 30 Sep 2026 15:52:42 -0700
Subject: [PATCH 1/2] [CIR] Correct array-subscript-ordering

We had the comment about the ordering, but didn't get it right!  C++17
requires we go left-to-right ordering, rather than it being UB, so
classic-codegen was changed at one point to do this all the time.
However, we only got a partial implementation of this, which results in
side-effects being noticable.  This showed up in a test suite.

This patch does its best to just copy from classic-codegen.
---
 clang/lib/CIR/CodeGen/CIRGenExpr.cpp          | 26 +++++++++----
 .../CIR/CodeGen/amdgpu-array-addrspace.cpp    |  2 +-
 .../CIR/CodeGen/array-subscript-order.cpp     | 38 +++++++++++++++++++
 clang/test/CIR/CodeGen/array.cpp              | 14 +++----
 clang/test/CIR/CodeGen/bitint-record-layout.c |  6 +--
 clang/test/CIR/CodeGen/no-odr-use.cpp         |  4 +-
 clang/test/CIR/CodeGen/pointers.cpp           |  6 +--
 clang/test/CIR/CodeGen/union.c                |  4 +-
 clang/test/CIR/CodeGen/vla.c                  | 16 ++++----
 .../CIR/CodeGenBuiltins/builtin-constant-p.c  |  2 +-
 clang/test/CIR/CodeGenOpenACC/combined-copy.c |  2 +-
 11 files changed, 84 insertions(+), 36 deletions(-)
 create mode 100644 clang/test/CIR/CodeGen/array-subscript-order.cpp

diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index d285800111c45..3e0e343f337ed 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -1383,11 +1383,16 @@ CIRGenFunction::emitArraySubscriptExpr(const 
clang::ArraySubscriptExpr *e) {
 
   // The index must always be an integer, which is not an aggregate.  Emit it
   // in lexical order (this complexity is, sadly, required by C++17).
-  assert((e->getIdx() == e->getLHS() || e->getIdx() == e->getRHS()) &&
-         "index was neither LHS nor RHS");
-
-  auto emitIdxAfterBase = [&](bool promote) -> mlir::Value {
-    mlir::Value idx = emitScalarExpr(e->getIdx());
+  mlir::Value idxPre = (e->getLHS() == e->getIdx())
+                           ? emitScalarExpr(e->getIdx())
+                           : mlir::Value();
+
+  auto emitIdxAfterBase = [&, idxPre](bool promote) -> mlir::Value {
+    mlir::Value idx = idxPre;
+    if (e->getLHS() != e->getIdx()) {
+      assert(e->getRHS() == e->getIdx() && "index was neither LHS nor RHS");
+      idx = emitScalarExpr(e->getIdx());
+    }
 
     assert(!cir::MissingFeatures::sanitizers());
 
@@ -1411,13 +1416,16 @@ CIRGenFunction::emitArraySubscriptExpr(const 
clang::ArraySubscriptExpr *e) {
 
     return idx;
   };
+  // This is captured by value above, using it after this is an error, so clear
+  // it to make sure no one is depending on it (mirrors classic codegen).
+  idxPre = mlir::Value();
 
   // If the base is a vector type, then we are forming a vector element
   // with this subscript.
   if (e->getBase()->getType()->isSubscriptableVectorType() &&
       !isa<ExtVectorElementExpr>(e->getBase())) {
-    const mlir::Value idx = emitIdxAfterBase(/*promote=*/false);
     const LValue lv = emitLValue(e->getBase());
+    const mlir::Value idx = emitIdxAfterBase(/*promote=*/false);
     return LValue::makeVectorElt(lv.getAddress(), idx, e->getBase()->getType(),
                                  lv.getBaseInfo());
   }
@@ -1429,11 +1437,10 @@ CIRGenFunction::emitArraySubscriptExpr(const 
clang::ArraySubscriptExpr *e) {
     return {};
   }
 
-  mlir::Value idx = emitIdxAfterBase(/*promote=*/true);
-
   // Handle the extvector case we ignored above.
   if (isa<ExtVectorElementExpr>(e->getBase())) {
     const LValue lv = emitLValue(e->getBase());
+    const mlir::Value idx = emitIdxAfterBase(/*promote=*/true);
     Address addr = emitExtVectorElementLValue(lv, cgm.getLoc(e->getExprLoc()));
 
     QualType elementType = 
lv.getType()->castAs<VectorType>()->getElementType();
@@ -1451,6 +1458,7 @@ CIRGenFunction::emitArraySubscriptExpr(const 
clang::ArraySubscriptExpr *e) {
     // it.  It needs to be emitted first in case it's what captures
     // the VLA bounds.
     Address addr = emitPointerWithAlignment(e->getBase());
+    mlir::Value idx = emitIdxAfterBase(/*promote=*/true);
 
     // The element count here is the total number of non-VLA elements.
     mlir::Value numElements = getVLASize(vla).numElts;
@@ -1480,6 +1488,7 @@ CIRGenFunction::emitArraySubscriptExpr(const 
clang::ArraySubscriptExpr *e) {
       arrayLV = emitArraySubscriptExpr(ase);
     else
       arrayLV = emitLValue(array);
+    mlir::Value idx = emitIdxAfterBase(/*promote=*/true);
 
     // Propagate the alignment from the array itself to the result.
     const Address addr = emitArraySubscriptPtr(
@@ -1502,6 +1511,7 @@ CIRGenFunction::emitArraySubscriptExpr(const 
clang::ArraySubscriptExpr *e) {
 
   LValueBaseInfo eltBaseInfo;
   const Address ptrAddr = emitPointerWithAlignment(e->getBase(), &eltBaseInfo);
+  const mlir::Value idx = emitIdxAfterBase(/*promote=*/true);
   // Propagate the alignment from the array itself to the result.
   const Address addxr = emitArraySubscriptPtr(
       *this, cgm.getLoc(e->getBeginLoc()), cgm.getLoc(e->getEndLoc()), ptrAddr,
diff --git a/clang/test/CIR/CodeGen/amdgpu-array-addrspace.cpp 
b/clang/test/CIR/CodeGen/amdgpu-array-addrspace.cpp
index 2ff665edf2dc1..a11b9289303fb 100644
--- a/clang/test/CIR/CodeGen/amdgpu-array-addrspace.cpp
+++ b/clang/test/CIR/CodeGen/amdgpu-array-addrspace.cpp
@@ -35,7 +35,7 @@ void pass_global_array() {
 
 // CIR-LABEL: cir.func{{.*}} @_Z18index_global_arrayi
 // CIR:         %[[ARR:.*]] = cir.get_global @globalArr : 
!cir.ptr<!cir.array<!s32i x 10>, target_address_space(1)>
-// CIR-NEXT:    %[[ELEM:.*]] = cir.get_element %[[ARR]][%{{.*}} : !s64i] : 
!cir.ptr<!cir.array<!s32i x 10>, target_address_space(1)> -> !cir.ptr<!s32i, 
target_address_space(1)>
+// CIR:         %[[ELEM:.*]] = cir.get_element %[[ARR]][%{{.*}} : !s64i] : 
!cir.ptr<!cir.array<!s32i x 10>, target_address_space(1)> -> !cir.ptr<!s32i, 
target_address_space(1)>
 // CIR-NEXT:    %{{.*}} = cir.load align(4) %[[ELEM]] : !cir.ptr<!s32i, 
target_address_space(1)>, !s32i
 
 // LLVM-LABEL: define{{.*}} i32 @_Z18index_global_arrayi
diff --git a/clang/test/CIR/CodeGen/array-subscript-order.cpp 
b/clang/test/CIR/CodeGen/array-subscript-order.cpp
new file mode 100644
index 0000000000000..130262959de80
--- /dev/null
+++ b/clang/test/CIR/CodeGen/array-subscript-order.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o 
%t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o 
%t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
+
+int *baseFn();
+int idxFn();
+
+// baseFn() is written first, so it must be evaluated before idxFn().
+int test1(void) {
+  return baseFn()[idxFn()];
+}
+
+// CIR-LABEL: cir.func{{.*}} @_Z5test1v
+// CIR:         %[[BASE:.*]] = cir.call @_Z6baseFnv()
+// CIR-NEXT:    %[[IDX:.*]] = cir.call @_Z5idxFnv()
+// CIR:         cir.ptr_stride %[[BASE]], {{.*}}
+
+// LLVM-LABEL: define{{.*}} i32 @_Z5test1v()
+// LLVM:         %[[BASE:.*]] = call {{.*}} ptr @_Z6baseFnv()
+// LLVM-NEXT:    %[[IDX:.*]] = call {{.*}} i32 @_Z5idxFnv()
+// LLVM:         getelementptr {{.*}}i32, ptr %[[BASE]],
+
+int test2(void) {
+  return idxFn()[baseFn()];
+}
+
+// CIR-LABEL: cir.func{{.*}} @_Z5test2v
+// CIR:         %[[IDX:.*]] = cir.call @_Z5idxFnv()
+// CIR-NEXT:    %[[BASE:.*]] = cir.call @_Z6baseFnv()
+// CIR:         cir.ptr_stride %[[BASE]], {{.*}}
+
+// LLVM-LABEL: define{{.*}} i32 @_Z5test2v()
+// LLVM:         %[[IDX:.*]] = call {{.*}} i32 @_Z5idxFnv()
+// LLVM-NEXT:    %[[BASE:.*]] = call {{.*}} ptr @_Z6baseFnv()
+// LLVM:         getelementptr {{.*}}i32, ptr %[[BASE]],
diff --git a/clang/test/CIR/CodeGen/array.cpp b/clang/test/CIR/CodeGen/array.cpp
index c17ce8f30d771..9b60dd96789b9 100644
--- a/clang/test/CIR/CodeGen/array.cpp
+++ b/clang/test/CIR/CodeGen/array.cpp
@@ -262,9 +262,9 @@ void func4() {
 // CIR: %[[INIT:.*]] = cir.alloca "e" {{.*}} init : !cir.ptr<!s32i>
 // CIR: %[[CONST:.*]] = cir.get_global @[[FUNC4_ARR]] : 
!cir.ptr<!cir.array<!cir.array<!s32i x 1> x 2>>
 // CIR: cir.copy %[[CONST]] to %[[ARR]] : !cir.ptr<!cir.array<!cir.array<!s32i 
x 1> x 2>>
-// CIR: %[[IDX:.*]] = cir.const #cir.int<0> : !s64i
 // CIR: %[[IDX_1:.*]] = cir.const #cir.int<1> : !s64i
 // CIR: %[[ARR_1:.*]] = cir.get_element %[[ARR]][%[[IDX_1]] : !s64i] : 
!cir.ptr<!cir.array<!cir.array<!s32i x 1> x 2>> -> !cir.ptr<!cir.array<!s32i x 
1>>
+// CIR: %[[IDX:.*]] = cir.const #cir.int<0> : !s64i
 // CIR: %[[ELE_0:.*]] = cir.get_element %[[ARR_1]][%[[IDX]] : !s64i] : 
!cir.ptr<!cir.array<!s32i x 1>> -> !cir.ptr<!s32i>
 // CIR: %[[TMP:.*]] = cir.load{{.*}} %[[ELE_0]] : !cir.ptr<!s32i>, !s32i
 // CIR: cir.store{{.*}} %[[TMP]], %[[INIT]] : !s32i, !cir.ptr<!s32i>
@@ -361,13 +361,13 @@ void func8(int arr[10]) {
 // CIR:  %[[INIT:.*]] = cir.alloca "e" {{.*}} init : !cir.ptr<!s32i>
 // CIR:  %[[INIT_2:.*]] = cir.alloca "e2" {{.*}} init : !cir.ptr<!s32i>
 // CIR:  cir.store{{.*}} %[[ARG]], %[[ARR]] : !cir.ptr<!s32i>, 
!cir.ptr<!cir.ptr<!s32i>>
-// CIR:  %[[IDX:.*]] = cir.const #cir.int<0> : !s64i
 // CIR:  %[[TMP_1:.*]] = cir.load{{.*}} %[[ARR]] : !cir.ptr<!cir.ptr<!s32i>>, 
!cir.ptr<!s32i>
+// CIR:  %[[IDX:.*]] = cir.const #cir.int<0> : !s64i
 // CIR:  %[[ELE_0:.*]] = cir.ptr_stride %[[TMP_1]], %[[IDX]] : 
(!cir.ptr<!s32i>, !s64i) -> !cir.ptr<!s32i>
 // CIR:  %[[TMP_2:.*]] = cir.load{{.*}} %[[ELE_0]] : !cir.ptr<!s32i>, !s32i
 // CIR:  cir.store{{.*}} %[[TMP_2]], %[[INIT]] : !s32i, !cir.ptr<!s32i>
-// CIR:  %[[IDX_1:.*]] = cir.const #cir.int<1> : !s64i
 // CIR:  %[[TMP_3:.*]] = cir.load{{.*}} %[[ARR]] : !cir.ptr<!cir.ptr<!s32i>>, 
!cir.ptr<!s32i>
+// CIR:  %[[IDX_1:.*]] = cir.const #cir.int<1> : !s64i
 // CIR:  %[[ELE_1:.*]] = cir.ptr_stride %[[TMP_3]], %[[IDX_1]] : 
(!cir.ptr<!s32i>, !s64i) -> !cir.ptr<!s32i>
 // CIR:  %[[TMP_4:.*]] = cir.load{{.*}} %[[ELE_1]] : !cir.ptr<!s32i>, !s32i
 // CIR:  cir.store{{.*}} %[[TMP_4]], %[[INIT_2]] : !s32i, !cir.ptr<!s32i>
@@ -407,10 +407,10 @@ void func9(int arr[10][5]) {
 // CIR:  %[[ARR:.*]] = cir.alloca "arr" {{.*}} init : 
!cir.ptr<!cir.ptr<!cir.array<!s32i x 5>>>
 // CIR:  %[[INIT:.*]] = cir.alloca "e" {{.*}} init : !cir.ptr<!s32i>
 // CIR:  cir.store{{.*}} %[[ARG]], %[[ARR]] : !cir.ptr<!cir.array<!s32i x 5>>, 
!cir.ptr<!cir.ptr<!cir.array<!s32i x 5>>>
-// CIR:  %[[IDX:.*]] = cir.const #cir.int<2> : !s64i
-// CIR:  %[[IDX_1:.*]] = cir.const #cir.int<1> : !s64i
 // CIR:  %[[TMP_1:.*]] = cir.load{{.*}} %[[ARR]] : 
!cir.ptr<!cir.ptr<!cir.array<!s32i x 5>>>, !cir.ptr<!cir.array<!s32i x 5>>
+// CIR:  %[[IDX_1:.*]] = cir.const #cir.int<1> : !s64i
 // CIR:  %[[ARR_1:.*]] = cir.ptr_stride %[[TMP_1]], %[[IDX_1]] : 
(!cir.ptr<!cir.array<!s32i x 5>>, !s64i) -> !cir.ptr<!cir.array<!s32i x 5>>
+// CIR:  %[[IDX:.*]] = cir.const #cir.int<2> : !s64i
 // CIR: %[[ARR_1_2:.*]] = cir.get_element %[[ARR_1]][%[[IDX]] : !s64i] : 
!cir.ptr<!cir.array<!s32i x 5>> -> !cir.ptr<!s32i>
 // CIR:  %[[TMP_2:.*]] = cir.load{{.*}} %[[ARR_1_2]] : !cir.ptr<!s32i>, !s32i
 // CIR:  cir.store{{.*}} %[[TMP_2]], %[[INIT]] : !s32i, !cir.ptr<!s32i>
@@ -442,8 +442,8 @@ void func10(int *a) {
 // CIR: %[[ARR:.*]] = cir.alloca "a" {{.*}} init : !cir.ptr<!cir.ptr<!s32i>>
 // CIR: %[[INIT:.*]] = cir.alloca "e" {{.*}} init : !cir.ptr<!s32i>
 // CIR: cir.store{{.*}} %[[ARG]], %[[ARR]] : !cir.ptr<!s32i>, 
!cir.ptr<!cir.ptr<!s32i>>
-// CIR: %[[IDX:.*]] = cir.const #cir.int<5> : !s64i
 // CIR: %[[TMP_1:.*]] = cir.load{{.*}} %[[ARR]] : !cir.ptr<!cir.ptr<!s32i>>, 
!cir.ptr<!s32i>
+// CIR: %[[IDX:.*]] = cir.const #cir.int<5> : !s64i
 // CIR: %[[ELE:.*]] = cir.ptr_stride %[[TMP_1]], %[[IDX]] : (!cir.ptr<!s32i>, 
!s64i) -> !cir.ptr<!s32i>
 // CIR: %[[TMP_2:.*]] = cir.load{{.*}} %[[ELE]] : !cir.ptr<!s32i>, !s32i
 // CIR: cir.store{{.*}} %[[TMP_2]], %[[INIT]] : !s32i, !cir.ptr<!s32i>
@@ -583,8 +583,8 @@ char access_last_element_of_huge_array() {
 }
 
 // CIR: cir.func{{.*}} @_Z33access_last_element_of_huge_arrayv
-// CIR:   %[[IDX:.*]] = cir.const #cir.int<2305843009213693950> : !u64i
 // CIR:   %[[HUGE:.*]] = cir.get_global @huge : !cir.ptr<!cir.array<!s8i x 
2305843009213693951>>
+// CIR:   %[[IDX:.*]] = cir.const #cir.int<2305843009213693950> : !u64i
 // CIR:   %[[ELE:.*]] = cir.get_element %[[HUGE]][%[[IDX]] : !u64i] : 
!cir.ptr<!cir.array<!s8i x 2305843009213693951>> -> !cir.ptr<!s8i>
 // CIR:   cir.load{{.*}} %[[ELE]] : !cir.ptr<!s8i>, !s8i
 
diff --git a/clang/test/CIR/CodeGen/bitint-record-layout.c 
b/clang/test/CIR/CodeGen/bitint-record-layout.c
index a9a9b7a21b55b..70b6638609bcc 100644
--- a/clang/test/CIR/CodeGen/bitint-record-layout.c
+++ b/clang/test/CIR/CodeGen/bitint-record-layout.c
@@ -200,8 +200,8 @@ struct Outer2 nestedArr2[2] = {{1, 222}, {3, 444}};
 _BitInt(128) get_bi(void) { return l128[1].bi; }
 // CIR-LABEL: cir.func no_inline dso_local @get_bi() -> !s128i_bitint
 // CIR-NEXT: %[[RET_ALLOC:.*]] = cir.alloca "__retval" align(8) : 
!cir.ptr<!s128i_bitint>
-// CIR-NEXT: %[[ONE:.*]] = cir.const #cir.int<1> : !s64i
 // CIR-NEXT: %[[GET_GLOB:.*]] = cir.get_global @l128 : 
!cir.ptr<!cir.array<!rec_Last128 x 2>>
+// CIR-NEXT: %[[ONE:.*]] = cir.const #cir.int<1> : !s64i
 // CIR-NEXT: %[[ARR_GEP:.*]] = cir.get_element %[[GET_GLOB]][%[[ONE]] : !s64i] 
: !cir.ptr<!cir.array<!rec_Last128 x 2>> -> !cir.ptr<!rec_Last128>
 // CIR-NEXT: %[[GET_BI:.*]] = cir.get_member %[[ARR_GEP]][2] {name = "bi"} : 
!cir.ptr<!rec_Last128> -> !cir.ptr<!s128i_bitint>
 // CIR-NEXT: %[[LOAD_BI:.*]] = cir.load align(8) %[[GET_BI]] : 
!cir.ptr<!s128i_bitint>, !s128i_bitint
@@ -214,11 +214,11 @@ _BitInt(128) get_bi(void) { return l128[1].bi; }
 _BitInt(128) get_bi2(void) { return arrMem[1].bi[1]; }
 // CIR-LABEL: cir.func no_inline dso_local @get_bi2() -> !s128i_bitint 
attributes {"cir.target-features" = "+cx8,+mmx,+sse,+sse2,+x87", nothrow} {
 // CIR-NEXT: %[[RET_ALLOC:.*]] = cir.alloca "__retval" align(8) : 
!cir.ptr<!s128i_bitint>
-// CIR-NEXT: %[[ONE:.*]] = cir.const #cir.int<1> : !s64i
-// CIR-NEXT: %[[ONE_2:.*]] = cir.const #cir.int<1> : !s64i
 // CIR-NEXT: %[[GET_GLOB:.*]] = cir.get_global @arrMem : 
!cir.ptr<!cir.array<!rec_ArrMem x 2>>
+// CIR-NEXT: %[[ONE_2:.*]] = cir.const #cir.int<1> : !s64i
 // CIR-NEXT: %[[ARR_GEP:.*]] = cir.get_element %[[GET_GLOB]][%[[ONE_2]] : 
!s64i] : !cir.ptr<!cir.array<!rec_ArrMem x 2>> -> !cir.ptr<!rec_ArrMem>
 // CIR-NEXT: %[[GET_BI_ARR:.*]] = cir.get_member %[[ARR_GEP]][2] {name = "bi"} 
: !cir.ptr<!rec_ArrMem> -> !cir.ptr<!cir.array<!s128i_bitint x 2>>
+// CIR-NEXT: %[[ONE:.*]] = cir.const #cir.int<1> : !s64i
 // CIR-NEXT: %[[GET_BI_ELT:.*]] = cir.get_element %[[GET_BI_ARR]][%[[ONE]] : 
!s64i] : !cir.ptr<!cir.array<!s128i_bitint x 2>> -> !cir.ptr<!s128i_bitint>
 // CIR-NEXT: %[[LOAD_BI:.*]] = cir.load align(8) %[[GET_BI_ELT]] : 
!cir.ptr<!s128i_bitint>, !s128i_bitint
 // CIR-NEXT: cir.store %[[LOAD_BI]], %[[RET_ALLOC]] : !s128i_bitint, 
!cir.ptr<!s128i_bitint>
diff --git a/clang/test/CIR/CodeGen/no-odr-use.cpp 
b/clang/test/CIR/CodeGen/no-odr-use.cpp
index f325a96a3576f..3b37316588a8b 100644
--- a/clang/test/CIR/CodeGen/no-odr-use.cpp
+++ b/clang/test/CIR/CodeGen/no-odr-use.cpp
@@ -79,12 +79,12 @@ int f(int i) {
         // OGCG: getelementptr inbounds i8, ptr @__const._Z1fi.a, i64 %{{.*}}
         // OGCG: load i32
         ? a.*p
+        // CIR: %[[A:.*]] = cir.get_global @[[F_A]] : !cir.ptr<!rec_A>
+        // CIR: %[[Y:.*]] = cir.get_member %[[A]][1] {name = "y"} : 
!cir.ptr<!rec_A> -> !cir.ptr<!cir.array<!s32i x 2>>
         // CIR: %[[TWO:.*]] = cir.const #cir.int<2> : !s32i
         // CIR: %[[N:.*]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!s32i>, !s32i
         // CIR: %[[SUB:.*]] = cir.sub nsw %[[TWO]], %[[N]] : !s32i
         // CIR: %[[SUB_64:.*]] = cir.cast integral %[[SUB]] : !s32i -> !s64i
-        // CIR: %[[A:.*]] = cir.get_global @[[F_A]] : !cir.ptr<!rec_A>
-        // CIR: %[[Y:.*]] = cir.get_member %[[A]][1] {name = "y"} : 
!cir.ptr<!rec_A> -> !cir.ptr<!cir.array<!s32i x 2>>
         // CIR: cir.get_element %[[Y]][%[[SUB_64]] : !s64i] : 
!cir.ptr<!cir.array<!s32i x 2>> -> !cir.ptr<!s32i>
 
         // LLVM: getelementptr [2 x i32], ptr getelementptr inbounds nuw 
({{.*}} @[[F_A]], i64 4), i32 0, i64 %{{.*}}
diff --git a/clang/test/CIR/CodeGen/pointers.cpp 
b/clang/test/CIR/CodeGen/pointers.cpp
index 956116a834e6c..2ea62874d3e49 100644
--- a/clang/test/CIR/CodeGen/pointers.cpp
+++ b/clang/test/CIR/CodeGen/pointers.cpp
@@ -47,19 +47,19 @@ void foo(int *iptr, char *cptr, unsigned ustride) {
 void testPointerSubscriptAccess(int *ptr) {
 // CHECK: testPointerSubscriptAccess
   ptr[1];
-  // CHECK: %[[#STRIDE:]] = cir.const #cir.int<1> : !s64i
   // CHECK: %[[#PTR:]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!s32i>>, 
!cir.ptr<!s32i>
+  // CHECK: %[[#STRIDE:]] = cir.const #cir.int<1> : !s64i
   // CHECK: cir.ptr_stride %[[#PTR]], %[[#STRIDE]] : (!cir.ptr<!s32i>, !s64i) 
-> !cir.ptr<!s32i>
 }
 
 void testPointerMultiDimSubscriptAccess(int **ptr) {
 // CHECK: testPointerMultiDimSubscriptAccess
   ptr[1][2];
-  // CHECK: %[[#STRIDE2:]] = cir.const #cir.int<2> : !s64i
-  // CHECK: %[[#STRIDE1:]] = cir.const #cir.int<1> : !s64i
   // CHECK: %[[#PTR1:]] = cir.load{{.*}} %{{.+}} : 
!cir.ptr<!cir.ptr<!cir.ptr<!s32i>>>, !cir.ptr<!cir.ptr<!s32i>>
+  // CHECK: %[[#STRIDE1:]] = cir.const #cir.int<1> : !s64i
   // CHECK: %[[#PTR2:]] = cir.ptr_stride %[[#PTR1]], %[[#STRIDE1]] : 
(!cir.ptr<!cir.ptr<!s32i>>, !s64i) -> !cir.ptr<!cir.ptr<!s32i>>
   // CHECK: %[[#PTR3:]] = cir.load{{.*}} %[[#PTR2]] : 
!cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
+  // CHECK: %[[#STRIDE2:]] = cir.const #cir.int<2> : !s64i
   // CHECK: cir.ptr_stride %[[#PTR3]], %[[#STRIDE2]] : (!cir.ptr<!s32i>, 
!s64i) -> !cir.ptr<!s32i>
 }
 
diff --git a/clang/test/CIR/CodeGen/union.c b/clang/test/CIR/CodeGen/union.c
index ef0ebd544f12b..a655bcce9a8f7 100644
--- a/clang/test/CIR/CodeGen/union.c
+++ b/clang/test/CIR/CodeGen/union.c
@@ -184,8 +184,8 @@ void f3(union U3 u) {
 // CIR-NEXT:   %[[U:.*]] = cir.alloca "u" align(1) init : !cir.ptr<!rec_U3>
 // CIR-NEXT:   cir.store{{.*}} %[[ARG_VAL]], %[[U]] : !rec_U3, 
!cir.ptr<!rec_U3>
 // CIR-NEXT:   %[[ZERO:.*]] = cir.const #cir.int<0> : !s8i
-// CIR-NEXT:   %[[IDX:.*]] = cir.const #cir.int<2> : !s64i
 // CIR-NEXT:   %[[C_PTR:.*]] = cir.get_member %[[U]][0] {name = "c"} : 
!cir.ptr<!rec_U3> -> !cir.ptr<!cir.array<!s8i x 5>>
+// CIR-NEXT:   %[[IDX:.*]] = cir.const #cir.int<2> : !s64i
 // CIR-NEXT:   %[[ELEM_PTR:.*]] = cir.get_element %[[C_PTR]][%[[IDX]] : !s64i] 
: !cir.ptr<!cir.array<!s8i x 5>> -> !cir.ptr<!s8i>
 // CIR-NEXT:   cir.store{{.*}} %[[ZERO]], %[[ELEM_PTR]] : !s8i, !cir.ptr<!s8i>
 // CIR-NEXT:   cir.return
@@ -220,8 +220,8 @@ void f5(union U4 u) {
 // CIR-NEXT:   %[[U:.*]] = cir.alloca "u" align(4) init : !cir.ptr<!rec_U4>
 // CIR-NEXT:   cir.store{{.*}} %[[ARG_VAL]], %[[U]] : !rec_U4, 
!cir.ptr<!rec_U4>
 // CIR-NEXT:   %[[CHAR_VAL:.*]] = cir.const #cir.int<65> : !s8i
-// CIR-NEXT:   %[[IDX:.*]] = cir.const #cir.int<4> : !s64i
 // CIR-NEXT:   %[[C_PTR:.*]] = cir.get_member %[[U]][0] {name = "c"} : 
!cir.ptr<!rec_U4> -> !cir.ptr<!cir.array<!s8i x 5>>
+// CIR-NEXT:   %[[IDX:.*]] = cir.const #cir.int<4> : !s64i
 // CIR-NEXT:   %[[ELEM_PTR:.*]] = cir.get_element %[[C_PTR]][%[[IDX]] : !s64i] 
: !cir.ptr<!cir.array<!s8i x 5>> -> !cir.ptr<!s8i>
 // CIR-NEXT:   cir.store{{.*}} %[[CHAR_VAL]], %[[ELEM_PTR]] : !s8i, 
!cir.ptr<!s8i>
 // CIR-NEXT:   cir.return
diff --git a/clang/test/CIR/CodeGen/vla.c b/clang/test/CIR/CodeGen/vla.c
index 5c0076c36a6ce..6ec3b6f22a159 100644
--- a/clang/test/CIR/CodeGen/vla.c
+++ b/clang/test/CIR/CodeGen/vla.c
@@ -393,17 +393,17 @@ void vla_subscript_expr() {
 // CIR: %[[CONST_5:.*]] = cir.const #cir.int<5> : !u64i
 // CIR: cir.store {{.*}} %[[CONST_5]], %[[N_ADDR]] : !u64i, !cir.ptr<!u64i>
 // CIR: %[[CONST_0_VAL:.*]] = cir.const #cir.int<0> : !s32i
-// CIR: %[[CONST_5:.*]] = cir.const #cir.int<5> : !s64i
-// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s64i
 // CIR: %[[TMP_N:.*]] = cir.load {{.*}} %[[N_ADDR]] : !cir.ptr<!u64i>, !u64i
 // CIR: %[[A_VAL:.*]] = cir.cast bitcast %[[A_ADDR]] : 
!cir.ptr<!cir.ptr<!cir.ptr<!s32i>>> -> !cir.ptr<!cir.ptr<!s32i>>
 // CIR: cir.store {{.*}} %[[A_VAL]], %[[COMPOUND_ADDR]] : 
!cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!cir.ptr<!cir.ptr<!s32i>>>
 // CIR: %[[TMP_COMPOUND:.*]] = cir.load {{.*}} %[[COMPOUND_ADDR]] : 
!cir.ptr<!cir.ptr<!cir.ptr<!s32i>>>, !cir.ptr<!cir.ptr<!s32i>>
+// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s64i
 // CIR: %[[COMPOUND_PTR:.*]] = cir.ptr_stride %[[TMP_COMPOUND]], %[[CONST_0]] 
: (!cir.ptr<!cir.ptr<!s32i>>, !s64i) -> !cir.ptr<!cir.ptr<!s32i>>
 // CIR: %[[TMP_COMPOUND:.*]] = cir.load {{.*}} %[[COMPOUND_PTR]] : 
!cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
 // CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !u64i
 // CIR: %[[VLA_IDX:.*]] = cir.mul nsw %[[CONST_1]], %[[TMP_N]] : !u64i
 // CIR: %[[VLA_A_PTR:.*]] = cir.ptr_stride %[[TMP_COMPOUND]], %[[VLA_IDX]] : 
(!cir.ptr<!s32i>, !u64i) -> !cir.ptr<!s32i>
+// CIR: %[[CONST_5:.*]] = cir.const #cir.int<5> : !s64i
 // CIR: %[[ELEM_5_PTR:.*]] = cir.ptr_stride %[[VLA_A_PTR]], %[[CONST_5]] : 
(!cir.ptr<!s32i>, !s64i) -> !cir.ptr<!s32i>
 // CIR: cir.store {{.*}} %[[CONST_0_VAL]], %[[ELEM_5_PTR]] : !s32i, 
!cir.ptr<!s32i>
 
@@ -450,14 +450,14 @@ double vla_param_2d(int n, double m[n][n], int i, int j) {
 // CIR:   cir.store{{.*}} %[[J_ARG]], %[[J_ADDR]]
 // CIR:   %[[N:.*]] = cir.load{{.*}} %[[N_ADDR]]
 // CIR:   %[[VLA_SIZE:.*]] = cir.cast integral %[[N]] : !s32i -> !u64i
-// CIR:   %[[J:.*]] = cir.load{{.*}} %[[J_ADDR]]
-// CIR:   %[[J_EXT:.*]] = cir.cast integral %[[J]] : !s32i -> !s64i
+// CIR:   %[[M:.*]] = cir.load{{.*}} %[[M_ADDR]]
 // CIR:   %[[I:.*]] = cir.load{{.*}} %[[I_ADDR]]
 // CIR:   %[[I_EXT_S:.*]] = cir.cast integral %[[I]] : !s32i -> !s64i
-// CIR:   %[[M:.*]] = cir.load{{.*}} %[[M_ADDR]]
 // CIR:   %[[I_EXT:.*]] = cir.cast integral %[[I_EXT_S]] : !s64i -> !u64i
 // CIR:   %[[ROW_OFF:.*]] = cir.mul nsw %[[I_EXT]], %[[VLA_SIZE]] : !u64i
 // CIR:   %[[ROW_PTR:.*]] = cir.ptr_stride %[[M]], %[[ROW_OFF]]
+// CIR:   %[[J:.*]] = cir.load{{.*}} %[[J_ADDR]]
+// CIR:   %[[J_EXT:.*]] = cir.cast integral %[[J]] : !s32i -> !s64i
 // CIR:   %[[ELEM_PTR:.*]] = cir.ptr_stride %[[ROW_PTR]], %[[J_EXT]]
 // CIR:   %[[ELEM:.*]] = cir.load{{.*}} %[[ELEM_PTR]] : !cir.ptr<!cir.double>, 
!cir.double
 
@@ -472,13 +472,13 @@ double vla_param_2d(int n, double m[n][n], int i, int j) {
 // LLVM:   store i32 %[[J_ARG]], ptr %[[J_ADDR]]
 // LLVM:   %[[N:.*]] = load i32, ptr %[[N_ADDR]]
 // LLVM:   %[[VLA_SIZE:.*]] = sext i32 %[[N]] to i64
-// LLVM:   %[[J:.*]] = load i32, ptr %[[J_ADDR]]
-// LLVM:   %[[J_EXT:.*]] = sext i32 %[[J]] to i64
+// LLVM:   %[[M:.*]] = load ptr, ptr %[[M_ADDR]]
 // LLVM:   %[[I:.*]] = load i32, ptr %[[I_ADDR]]
 // LLVM:   %[[I_EXT:.*]] = sext i32 %[[I]] to i64
-// LLVM:   %[[M:.*]] = load ptr, ptr %[[M_ADDR]]
 // LLVM:   %[[ROW_OFF:.*]] = mul nsw i64 %[[I_EXT]], %[[VLA_SIZE]]
 // LLVM:   %[[ROW_PTR:.*]] = getelementptr double, ptr %[[M]], i64 %[[ROW_OFF]]
+// LLVM:   %[[J:.*]] = load i32, ptr %[[J_ADDR]]
+// LLVM:   %[[J_EXT:.*]] = sext i32 %[[J]] to i64
 // LLVM:   %[[ELEM_PTR:.*]] = getelementptr double, ptr %[[ROW_PTR]], i64 
%[[J_EXT]]
 // LLVM:   %[[ELEM:.*]] = load double, ptr %[[ELEM_PTR]]
 
diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-constant-p.c 
b/clang/test/CIR/CodeGenBuiltins/builtin-constant-p.c
index 32dd4eac69335..f87f7805f4aa3 100644
--- a/clang/test/CIR/CodeGenBuiltins/builtin-constant-p.c
+++ b/clang/test/CIR/CodeGenBuiltins/builtin-constant-p.c
@@ -166,8 +166,8 @@ int test6(void) {
 }
 
 // CIR: cir.func {{.*}} @test6() -> !s32i
-// CIR:   %[[TWO:.*]] = cir.const #cir.int<2> : !s64i
 // CIR:   %[[ARR:.*]] = cir.get_global @arr : !cir.ptr<!cir.array<!s32i x 3>>
+// CIR:   %[[TWO:.*]] = cir.const #cir.int<2> : !s64i
 // CIR:   %[[ELE_PTR:.*]] = cir.get_element %[[ARR]][%[[TWO]] : !s64i] : 
!cir.ptr<!cir.array<!s32i x 3>> -> !cir.ptr<!s32i>
 // CIR:   %[[ELE:.*]] = cir.load{{.*}} %[[ELE_PTR]] : !cir.ptr<!s32i>, !s32i
 // CIR:   %[[IS_CONSTANT:.*]] = cir.is_constant %[[ELE]] : !s32i -> !cir.bool
diff --git a/clang/test/CIR/CodeGenOpenACC/combined-copy.c 
b/clang/test/CIR/CodeGenOpenACC/combined-copy.c
index da0c355d547fd..828ee49b2a29e 100644
--- a/clang/test/CIR/CodeGenOpenACC/combined-copy.c
+++ b/clang/test/CIR/CodeGenOpenACC/combined-copy.c
@@ -1086,8 +1086,8 @@ void copy_member_of_array_element_member() {
 
   #pragma acc parallel loop copy(outer.inner[2].b)
   for(int i = 0; i < 5; ++i);
-  // CHECK-NEXT: %[[TWO:.*]] = cir.const #cir.int<2> : !s64i
   // CHECK-NEXT: %[[GETINNER:.*]] = cir.get_member %[[OUTER]][0] {name = 
"inner"} : !cir.ptr<!rec_OuterTy> -> !cir.ptr<!cir.array<!rec_InnerTy x 4>>
+  // CHECK-NEXT: %[[TWO:.*]] = cir.const #cir.int<2> : !s64i
   // CHECK-NEXT: %[[GET_ELT:.*]] = cir.get_element %[[GETINNER]][%[[TWO]] : 
!s64i] : !cir.ptr<!cir.array<!rec_InnerTy x 4>> -> !cir.ptr<!rec_InnerTy>
   // CHECK-NEXT: %[[GETB:.*]] = cir.get_member %[[GET_ELT]][1] {name = "b"} : 
!cir.ptr<!rec_InnerTy> -> !cir.ptr<!s32i>
   // CHECK-NEXT: %[[COPYIN1:.*]] = acc.copyin varPtr(%[[GETB]] : 
!cir.ptr<!s32i>) dataClause(acc_copy) name("outer.inner[2].b") -> 
!cir.ptr<!s32i>

>From 58487861b14b959e98c8916b70eb8bc9ffc0c9cf Mon Sep 17 00:00:00 2001
From: erichkeane <[email protected]>
Date: Thu, 1 Oct 2026 06:45:49 -0700
Subject: [PATCH 2/2] Add extra commit line to check that we don't change
 behavior because of C++17.

---
 clang/test/CIR/CodeGen/array-subscript-order.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/clang/test/CIR/CodeGen/array-subscript-order.cpp 
b/clang/test/CIR/CodeGen/array-subscript-order.cpp
index 130262959de80..e4bc2d810c6d6 100644
--- a/clang/test/CIR/CodeGen/array-subscript-order.cpp
+++ b/clang/test/CIR/CodeGen/array-subscript-order.cpp
@@ -1,5 +1,10 @@
 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o 
%t.cir
 // RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+//
+// Should be the same, but sanity check that it doesn't change.
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++11 -fclangir 
-emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+//
 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o 
%t-cir.ll
 // RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to