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
