We were hitting a CIR verification error in some cases when a boolean expression was used as an index to an array because the GetElementOp verifier expected the index operand to be a fundamental integer type. To fix this, I'm updating the emitArraySubscriptExpr to cast index values to ptrDiffTy, which more closely matches what classic codegen does in the corrsponding code. The improved alignment with the classic codegen implementation caused some minor changes in generated IR that required some tests to be updated. Assisted-by: Cursor / claude-4.7-opus-high
577 lines
30 KiB
C++
577 lines
30 KiB
C++
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -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 -Wno-unused-value -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 -Wno-unused-value -emit-llvm %s -o %t.ll
|
|
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
|
|
|
|
// CIR-DAG: cir.global "private"{{.*}}constant cir_private @[[FUNC2_ARR:.*]] = #cir.const_array<[#cir.int<5> : !s32i, #cir.int<0> : !s32i]> : !cir.array<!s32i x 2>
|
|
// CIR-DAG: cir.global "private"{{.*}}constant cir_private @[[FUNC3_ARR:.*]] = #cir.const_array<[#cir.int<5> : !s32i, #cir.int<6> : !s32i]> : !cir.array<!s32i x 2>
|
|
// CIR-DAG: cir.global "private"{{.*}}constant cir_private @[[FUNC4_ARR:.*]] = #cir.const_array<[#cir.const_array<[#cir.int<5> : !s32i]> : !cir.array<!s32i x 1>, #cir.const_array<[#cir.int<6> : !s32i]> : !cir.array<!s32i x 1>]> : !cir.array<!cir.array<!s32i x 1> x 2>
|
|
// CIR-DAG: cir.global "private"{{.*}}constant cir_private @[[FUNC5_ARR:.*]] = #cir.const_array<[#cir.const_array<[#cir.int<5> : !s32i]> : !cir.array<!s32i x 1>, #cir.zero : !cir.array<!s32i x 1>]> : !cir.array<!cir.array<!s32i x 1> x 2>
|
|
// CIR-DAG: cir.global "private"{{.*}}constant cir_private @[[FUNC7_ARR:.*]] = #cir.zero : !cir.array<!cir.ptr<!s32i> x 1>
|
|
// CIR-DAG: cir.global "private"{{.*}}constant cir_private @[[COMPLEX_ARR:.*]] = #cir.const_array<[#cir.const_complex<#cir.fp<1.100000e+00> : !cir.float, #cir.fp<2.200000e+00> : !cir.float> : !cir.complex<!cir.float>, #cir.const_complex<#cir.fp<3.300000e+00> : !cir.float, #cir.fp<4.400000e+00> : !cir.float> : !cir.complex<!cir.float>]> : !cir.array<!cir.complex<!cir.float> x 2>
|
|
|
|
int a[10];
|
|
// CIR: cir.global external @a = #cir.zero : !cir.array<!s32i x 10>
|
|
|
|
// LLVM: @a = global [10 x i32] zeroinitializer
|
|
|
|
// OGCG: @a = global [10 x i32] zeroinitializer
|
|
|
|
int aa[10][5];
|
|
// CIR: cir.global external @aa = #cir.zero : !cir.array<!cir.array<!s32i x 5> x 10>
|
|
|
|
// LLVM: @aa = global [10 x [5 x i32]] zeroinitializer
|
|
|
|
// OGCG: @aa = global [10 x [5 x i32]] zeroinitializer
|
|
|
|
int c[10] = {};
|
|
// CIR: cir.global external @c = #cir.zero : !cir.array<!s32i x 10>
|
|
|
|
// LLVM: @c = global [10 x i32] zeroinitializer
|
|
|
|
// OGCG: @c = global [10 x i32] zeroinitializer
|
|
|
|
int d[3] = {1, 2, 3};
|
|
// CIR: cir.global external @d = #cir.const_array<[#cir.int<1> : !s32i, #cir.int<2> : !s32i, #cir.int<3> : !s32i]> : !cir.array<!s32i x 3>
|
|
|
|
// LLVM: @d = global [3 x i32] [i32 1, i32 2, i32 3]
|
|
|
|
// OGCG: @d = global [3 x i32] [i32 1, i32 2, i32 3]
|
|
|
|
int dd[3][2] = {{1, 2}, {3, 4}, {5, 6}};
|
|
// CIR: cir.global external @dd = #cir.const_array<[#cir.const_array<[#cir.int<1> : !s32i, #cir.int<2> : !s32i]> : !cir.array<!s32i x 2>, #cir.const_array<[#cir.int<3> : !s32i, #cir.int<4> : !s32i]> : !cir.array<!s32i x 2>, #cir.const_array<[#cir.int<5> : !s32i, #cir.int<6> : !s32i]> : !cir.array<!s32i x 2>]> : !cir.array<!cir.array<!s32i x 2> x 3>
|
|
|
|
// LLVM: @dd = global [3 x [2 x i32]] [
|
|
// LLVM: [2 x i32] [i32 1, i32 2], [2 x i32]
|
|
// LLVM: [i32 3, i32 4], [2 x i32] [i32 5, i32 6]]
|
|
|
|
// OGCG: @dd = global [3 x [2 x i32]] [
|
|
// OGCG: [2 x i32] [i32 1, i32 2], [2 x i32]
|
|
// OGCG: [i32 3, i32 4], [2 x i32] [i32 5, i32 6]]
|
|
|
|
int e[10] = {1, 2};
|
|
// CIR: cir.global external @e = #cir.const_record<{#cir.int<1> : !s32i, #cir.int<2> : !s32i, #cir.zero : !cir.array<!s32i x 8>}> : !rec_anon_struct
|
|
|
|
// LLVM: @e = global <{ i32, i32, [8 x i32] }> <{ i32 1, i32 2, [8 x i32] zeroinitializer }>
|
|
|
|
// OGCG: @e = global <{ i32, i32, [8 x i32] }> <{ i32 1, i32 2, [8 x i32] zeroinitializer }>
|
|
|
|
int f[5] = {1, 2};
|
|
// CIR: cir.global external @f = #cir.const_array<[#cir.int<1> : !s32i, #cir.int<2> : !s32i, #cir.int<0> : !s32i, #cir.int<0> : !s32i, #cir.int<0> : !s32i]> : !cir.array<!s32i x 5>
|
|
|
|
// LLVM: @f = global [5 x i32] [i32 1, i32 2, i32 0, i32 0, i32 0]
|
|
|
|
// OGCG: @f = global [5 x i32] [i32 1, i32 2, i32 0, i32 0, i32 0]
|
|
|
|
int g[16] = {1, 2, 3, 4, 5, 6, 7, 8};
|
|
// CIR: cir.global external @g = #cir.const_record<{
|
|
// CIR-SAME: #cir.const_array<[#cir.int<1> : !s32i, #cir.int<2> : !s32i,
|
|
// CIR-SAME: #cir.int<3> : !s32i, #cir.int<4> : !s32i,
|
|
// CIR-SAME: #cir.int<5> : !s32i, #cir.int<6> : !s32i,
|
|
// CIR-SAME: #cir.int<7> : !s32i, #cir.int<8> : !s32i]>
|
|
// CIR-SAME: : !cir.array<!s32i x 8>,
|
|
// CIR-SAME: #cir.zero : !cir.array<!s32i x 8>}> : !rec_anon_struct1
|
|
|
|
// LLVM: @g = global <{ [8 x i32], [8 x i32] }>
|
|
// LLVM-SAME: <{ [8 x i32]
|
|
// LLVM-SAME: [i32 1, i32 2, i32 3, i32 4,
|
|
// LLVM-SAME: i32 5, i32 6, i32 7, i32 8],
|
|
// LLVM-SAME: [8 x i32] zeroinitializer }>
|
|
|
|
// OGCG: @g = global <{ [8 x i32], [8 x i32] }>
|
|
// OGCG-SAME: <{ [8 x i32]
|
|
// OGCG-SAME: [i32 1, i32 2, i32 3, i32 4,
|
|
// OGCG-SAME: i32 5, i32 6, i32 7, i32 8],
|
|
// OGCG-SAME: [8 x i32] zeroinitializer }>
|
|
|
|
// If we have explicit trailing zeros, those should still be combined into
|
|
// a zero initializer array.
|
|
int h[16] = {1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0};
|
|
|
|
// CIR: cir.global external @h = #cir.const_record<{
|
|
// CIR-SAME: #cir.const_array<[#cir.int<1> : !s32i, #cir.int<2> : !s32i,
|
|
// CIR-SAME: #cir.int<3> : !s32i, #cir.int<4> : !s32i,
|
|
// CIR-SAME: #cir.int<5> : !s32i, #cir.int<6> : !s32i,
|
|
// CIR-SAME: #cir.int<7> : !s32i, #cir.int<8> : !s32i]>
|
|
// CIR-SAME: : !cir.array<!s32i x 8>,
|
|
// CIR-SAME: #cir.zero : !cir.array<!s32i x 8>}> : !rec_anon_struct1
|
|
|
|
// LLVM: @h = global <{ [8 x i32], [8 x i32] }>
|
|
// LLVM-SAME: <{ [8 x i32]
|
|
// LLVM-SAME: [i32 1, i32 2, i32 3, i32 4,
|
|
// LLVM-SAME: i32 5, i32 6, i32 7, i32 8],
|
|
// LLVM-SAME: [8 x i32] zeroinitializer }>
|
|
|
|
// OGCG: @h = global <{ [8 x i32], [8 x i32] }>
|
|
// OGCG-SAME: <{ [8 x i32]
|
|
// OGCG-SAME: [i32 1, i32 2, i32 3, i32 4,
|
|
// OGCG-SAME: i32 5, i32 6, i32 7, i32 8],
|
|
// OGCG-SAME: [8 x i32] zeroinitializer }>
|
|
|
|
char huge[0x1FFFFFFFFFFFFFFFULL];
|
|
// CIR: cir.global external @huge = #cir.zero : !cir.array<!s8i x 2305843009213693951>
|
|
// LLVM: @huge = global [2305843009213693951 x i8] zeroinitializer
|
|
// OGCG: @huge = global [2305843009213693951 x i8] zeroinitializer
|
|
|
|
extern int b[10];
|
|
// CIR: cir.global "private" external @b : !cir.array<!s32i x 10>
|
|
// LLVM: @b = external global [10 x i32]
|
|
// OGCG: @b = external global [10 x i32]
|
|
|
|
extern int bb[10][5];
|
|
// CIR: cir.global "private" external @bb : !cir.array<!cir.array<!s32i x 5> x 10>
|
|
// LLVM: @bb = external global [10 x [5 x i32]]
|
|
// OGCG: @bb = external global [10 x [5 x i32]]
|
|
|
|
// This function is only here to make sure the external globals are emitted.
|
|
void reference_externs() {
|
|
b;
|
|
bb;
|
|
}
|
|
|
|
// OGCG: @[[FUN2_ARR:.*]] = private unnamed_addr constant [2 x i32] [i32 5, i32 0], align 4
|
|
// OGCG: @[[FUN3_ARR:.*]] = private unnamed_addr constant [2 x i32] [i32 5, i32 6], align 4
|
|
// OGCG: @[[FUN4_ARR:.*]] = private unnamed_addr constant [2 x [1 x i32]] [
|
|
// OGCG: [1 x i32] [i32 5], [1 x i32] [i32 6]], align 4
|
|
// OGCG: @[[FUN5_ARR:.*]] = private unnamed_addr constant [2 x [1 x i32]] [
|
|
// OGCG: [1 x i32] [i32 5], [1 x i32] zeroinitializer], align 4
|
|
|
|
void func() {
|
|
int arr[10];
|
|
int e = arr[0];
|
|
int e2 = arr[1];
|
|
}
|
|
|
|
// CIR: %[[ARR:.*]] = cir.alloca !cir.array<!s32i x 10>, !cir.ptr<!cir.array<!s32i x 10>>, ["arr"]
|
|
// CIR: %[[INIT:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["e", init]
|
|
// CIR: %[[INIT_2:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["e2", init]
|
|
// CIR: %[[IDX:.*]] = cir.const #cir.int<0> : !s64i
|
|
// CIR: %[[ELE_PTR:.*]] = cir.get_element %[[ARR]][%[[IDX]] : !s64i] : !cir.ptr<!cir.array<!s32i x 10>> -> !cir.ptr<!s32i>
|
|
// CIR: %[[TMP:.*]] = cir.load{{.*}} %[[ELE_PTR]] : !cir.ptr<!s32i>, !s32i
|
|
// CIR" cir.store %[[TMP]], %[[INIT]] : !s32i, !cir.ptr<!s32i>
|
|
// CIR: %[[IDX:.*]] = cir.const #cir.int<1> : !s64i
|
|
// CIR: %[[ELE_PTR:.*]] = cir.get_element %[[ARR]][%[[IDX]] : !s64i] : !cir.ptr<!cir.array<!s32i x 10>> -> !cir.ptr<!s32i>
|
|
// CIR: %[[TMP:.*]] = cir.load{{.*}} %[[ELE_PTR]] : !cir.ptr<!s32i>, !s32i
|
|
// CIR" cir.store %[[TMP]], %[[INIT_2]] : !s32i, !cir.ptr<!s32i>
|
|
|
|
// LLVM: define{{.*}} void @_Z4funcv(){{.*}}
|
|
// LLVM-NEXT: %[[ARR:.*]] = alloca [10 x i32], i64 1, align 16
|
|
// LLVM-NEXT: %[[INIT:.*]] = alloca i32, i64 1, align 4
|
|
// LLVM-NEXT: %[[INIT_2:.*]] = alloca i32, i64 1, align 4
|
|
// LLVM-NEXT: %[[ELE_PTR:.*]] = getelementptr [10 x i32], ptr %[[ARR]], i32 0, i64 0
|
|
// LLVM-NEXT: %[[TMP_1:.*]] = load i32, ptr %[[ELE_PTR]], align 16
|
|
// LLVM-NEXT: store i32 %[[TMP_1]], ptr %[[INIT]], align 4
|
|
// LLVM-NEXT: %[[ELE_PTR:.*]] = getelementptr [10 x i32], ptr %[[ARR]], i32 0, i64 1
|
|
// LLVM-NEXT: %[[TMP_2:.*]] = load i32, ptr %[[ELE_PTR]], align 4
|
|
// LLVM-NEXT: store i32 %[[TMP_2]], ptr %[[INIT_2]], align 4
|
|
|
|
// OGCG: %[[ARR:.*]] = alloca [10 x i32], align 16
|
|
// OGCG: %[[INIT:.*]] = alloca i32, align 4
|
|
// OGCG: %[[INIT_2:.*]] = alloca i32, align 4
|
|
// OGCG: %[[ELE_PTR:.*]] = getelementptr inbounds [10 x i32], ptr %[[ARR]], i64 0, i64 0
|
|
// OGCG: %[[TMP_1:.*]] = load i32, ptr %[[ELE_PTR]], align 16
|
|
// OGCG: store i32 %[[TMP_1]], ptr %[[INIT]], align 4
|
|
// OGCG: %[[ELE_PTR:.*]] = getelementptr inbounds [10 x i32], ptr %[[ARR]], i64 0, i64 1
|
|
// OGCG: %[[TMP_2:.*]] = load i32, ptr %[[ELE_PTR]], align 4
|
|
// OGCG: store i32 %[[TMP_2]], ptr %[[INIT_2]], align 4
|
|
|
|
void func2() {
|
|
int arr[2] = {5};
|
|
}
|
|
|
|
// CIR: %[[ARR2:.*]] = cir.alloca !cir.array<!s32i x 2>, !cir.ptr<!cir.array<!s32i x 2>>, ["arr", init]
|
|
// CIR: %[[CONST:.*]] = cir.get_global @[[FUNC2_ARR]] : !cir.ptr<!cir.array<!s32i x 2>>
|
|
// CIR: cir.copy %[[CONST]] to %[[ARR2]] : !cir.ptr<!cir.array<!s32i x 2>>
|
|
|
|
// LLVM: define{{.*}} void @_Z5func2v(){{.*}}
|
|
// LLVM: %[[ARR:.*]] = alloca [2 x i32], i64 1, align 4
|
|
// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %[[ARR]], ptr @[[FUNC2_ARR:.*]], i64 8, i1 false)
|
|
|
|
// OGCG: %[[ARR:.*]] = alloca [2 x i32], align 4
|
|
// OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[ARR]], ptr align 4 @[[FUN2_ARR]], i64 8, i1 false)
|
|
|
|
void func3() {
|
|
int arr[2] = {5, 6};
|
|
|
|
int idx = 1;
|
|
int e = arr[idx];
|
|
}
|
|
|
|
// CIR: %[[ARR:.*]] = cir.alloca !cir.array<!s32i x 2>, !cir.ptr<!cir.array<!s32i x 2>>, ["arr", init]
|
|
// CIR: %[[IDX:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["idx", init]
|
|
// CIR: %[[INIT:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["e", init]
|
|
// CIR: %[[CONST:.*]] = cir.get_global @[[FUNC3_ARR]] : !cir.ptr<!cir.array<!s32i x 2>>
|
|
// CIR: cir.copy %[[CONST]] to %[[ARR]] : !cir.ptr<!cir.array<!s32i x 2>>
|
|
// CIR: %[[IDX_V:.*]] = cir.const #cir.int<1> : !s32i
|
|
// CIR: cir.store{{.*}} %[[IDX_V]], %[[IDX]] : !s32i, !cir.ptr<!s32i>
|
|
// CIR: %[[TMP_IDX:.*]] = cir.load{{.*}} %[[IDX]] : !cir.ptr<!s32i>, !s32i
|
|
// CIR: %[[TMP_IDX_64:.*]] = cir.cast integral %[[TMP_IDX]] : !s32i -> !s64i
|
|
// CIR: %[[ELE_PTR:.*]] = cir.get_element %[[ARR]][%[[TMP_IDX_64]] : !s64i] : !cir.ptr<!cir.array<!s32i x 2>> -> !cir.ptr<!s32i>
|
|
// CIR: %[[ELE_TMP:.*]] = cir.load{{.*}} %[[ELE_PTR]] : !cir.ptr<!s32i>, !s32i
|
|
// CIR: cir.store{{.*}} %[[ELE_TMP]], %[[INIT]] : !s32i, !cir.ptr<!s32i>
|
|
|
|
// LLVM: define{{.*}} void @_Z5func3v(){{.*}}
|
|
// LLVM: %[[ARR:.*]] = alloca [2 x i32], i64 1, align 4
|
|
// LLVM: %[[IDX:.*]] = alloca i32, i64 1, align 4
|
|
// LLVM: %[[INIT:.*]] = alloca i32, i64 1, align 4
|
|
// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %[[ARR]], ptr @[[FUNC3_ARR:.*]], i64 8, i1 false)
|
|
// LLVM: store i32 1, ptr %[[IDX]], align 4
|
|
// LLVM: %[[TMP1:.*]] = load i32, ptr %[[IDX]], align 4
|
|
// LLVM: %[[IDX_I64:.*]] = sext i32 %[[TMP1]] to i64
|
|
// LLVM: %[[ELE:.*]] = getelementptr [2 x i32], ptr %[[ARR]], i32 0, i64 %[[IDX_I64]]
|
|
// LLVM: %[[TMP2:.*]] = load i32, ptr %[[ELE]], align 4
|
|
// LLVM: store i32 %[[TMP2]], ptr %[[INIT]], align 4
|
|
|
|
// OGCG: %[[ARR:.*]] = alloca [2 x i32], align 4
|
|
// OGCG: %[[IDX:.*]] = alloca i32, align 4
|
|
// OGCG: %[[INIT:.*]] = alloca i32, align 4
|
|
// OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[ARR]], ptr align 4 @[[FUN3_ARR]], i64 8, i1 false)
|
|
// OGCG: store i32 1, ptr %[[IDX]], align 4
|
|
// OGCG: %[[TMP:.*]] = load i32, ptr %[[IDX]], align 4
|
|
// OGCG: %[[IDX_I64:.*]] = sext i32 %[[TMP]] to i64
|
|
// OGCG: %[[ELE:.*]] = getelementptr inbounds [2 x i32], ptr %[[ARR]], i64 0, i64 %[[IDX_I64]]
|
|
// OGCG: %[[TMP_2:.*]] = load i32, ptr %[[ELE]], align 4
|
|
// OGCG: store i32 %[[TMP_2:.*]], ptr %[[INIT]], align 4
|
|
|
|
void func4() {
|
|
int arr[2][1] = {{5}, {6}};
|
|
int e = arr[1][0];
|
|
}
|
|
|
|
// CIR: %[[ARR:.*]] = cir.alloca !cir.array<!cir.array<!s32i x 1> x 2>, !cir.ptr<!cir.array<!cir.array<!s32i x 1> x 2>>, ["arr", init]
|
|
// CIR: %[[INIT:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["e", init]
|
|
// 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: %[[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>
|
|
|
|
// LLVM: define{{.*}} void @_Z5func4v(){{.*}}
|
|
// LLVM: %[[ARR:.*]] = alloca [2 x [1 x i32]], i64 1, align 4
|
|
// LLVM: %[[INIT:.*]] = alloca i32, i64 1, align 4
|
|
// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %[[ARR]], ptr @[[FUNC4_ARR:.*]], i64 8, i1 false)
|
|
// LLVM: %[[ARR_1:.*]] = getelementptr [2 x [1 x i32]], ptr %[[ARR]], i32 0, i64 1
|
|
// LLVM: %[[ELE_PTR:.*]] = getelementptr [1 x i32], ptr %[[ARR_1]], i32 0, i64 0
|
|
// LLVM: %[[TMP:.*]] = load i32, ptr %[[ELE_PTR]], align 4
|
|
// LLVM: store i32 %[[TMP]], ptr %[[INIT]], align 4
|
|
|
|
// OGCG: %[[ARR:.*]] = alloca [2 x [1 x i32]], align 4
|
|
// OGCG: %[[INIT:.*]] = alloca i32, align 4
|
|
// OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[ARR]], ptr align 4 @[[FUN4_ARR]], i64 8, i1 false)
|
|
// OGCG: %[[ARR_1:.*]] = getelementptr inbounds [2 x [1 x i32]], ptr %[[ARR]], i64 0, i64 1
|
|
// OGCG: %[[ARR_1_0:.*]] = getelementptr inbounds [1 x i32], ptr %[[ARR_1]], i64 0, i64 0
|
|
// OGCG: %[[TMP:.*]] = load i32, ptr %[[ARR_1_0]], align 4
|
|
// OGCG: store i32 %[[TMP]], ptr %[[INIT]], align 4
|
|
|
|
void func5() {
|
|
int arr[2][1] = {{5}};
|
|
}
|
|
|
|
// CIR: %[[ARR:.*]] = cir.alloca !cir.array<!cir.array<!s32i x 1> x 2>, !cir.ptr<!cir.array<!cir.array<!s32i x 1> x 2>>, ["arr", init]
|
|
// CIR: %[[CONST:.*]] = cir.get_global @[[FUNC5_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>>
|
|
|
|
// LLVM: define{{.*}} void @_Z5func5v(){{.*}}
|
|
// LLVM: %[[ARR:.*]] = alloca [2 x [1 x i32]], i64 1, align 4
|
|
// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %[[ARR]], ptr @[[FUNC5_ARR:.*]], i64 8, i1 false)
|
|
|
|
// OGCG: %[[ARR:.*]] = alloca [2 x [1 x i32]], align 4
|
|
// OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[ARR]], ptr align 4 @[[FUN5_ARR]], i64 8, i1 false)
|
|
|
|
void func6() {
|
|
int x = 4;
|
|
int arr[2] = { x, 5 };
|
|
}
|
|
|
|
// CIR: %[[VAR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init]
|
|
// CIR: %[[ARR:.*]] = cir.alloca !cir.array<!s32i x 2>, !cir.ptr<!cir.array<!s32i x 2>>, ["arr", init]
|
|
// CIR: %[[V:.*]] = cir.const #cir.int<4> : !s32i
|
|
// CIR: cir.store{{.*}} %[[V]], %[[VAR]] : !s32i, !cir.ptr<!s32i>
|
|
// CIR: %[[ARR_PTR:.*]] = cir.cast array_to_ptrdecay %[[ARR]] : !cir.ptr<!cir.array<!s32i x 2>> -> !cir.ptr<!s32i>
|
|
// CIR: %[[TMP:.*]] = cir.load{{.*}} %[[VAR]] : !cir.ptr<!s32i>, !s32i
|
|
// CIR: cir.store{{.*}} %[[TMP]], %[[ARR_PTR]] : !s32i, !cir.ptr<!s32i>
|
|
// CIR: %[[OFFSET:.*]] = cir.const #cir.int<1> : !s64i
|
|
// CIR: %[[ELE_PTR:.*]] = cir.ptr_stride %[[ARR_PTR]], %[[OFFSET]] : (!cir.ptr<!s32i>, !s64i) -> !cir.ptr<!s32i>
|
|
// CIR: %[[V1:.*]] = cir.const #cir.int<5> : !s32i
|
|
// CIR: cir.store{{.*}} %[[V1]], %[[ELE_PTR]] : !s32i, !cir.ptr<!s32i>
|
|
|
|
// LLVM: define{{.*}} void @_Z5func6v(){{.*}}
|
|
// LLVM: %[[VAR:.*]] = alloca i32, i64 1, align 4
|
|
// LLVM: %[[ARR:.*]] = alloca [2 x i32], i64 1, align 4
|
|
// LLVM: store i32 4, ptr %[[VAR]], align 4
|
|
// LLVM: %[[ELE_0:.*]] = getelementptr i32, ptr %[[ARR]], i32 0
|
|
// LLVM: %[[TMP:.*]] = load i32, ptr %[[VAR]], align 4
|
|
// LLVM: store i32 %[[TMP]], ptr %[[ELE_0]], align 4
|
|
// LLVM: %[[ELE_1:.*]] = getelementptr i32, ptr %[[ELE_0]], i64 1
|
|
// LLVM: store i32 5, ptr %[[ELE_1]], align 4
|
|
|
|
// OGCG: %[[VAR:.*]] = alloca i32, align 4
|
|
// OGCG: %[[ARR:.*]] = alloca [2 x i32], align 4
|
|
// OGCG: store i32 4, ptr %[[VAR]], align 4
|
|
// OGCG: %[[ELE_0:.*]] = load i32, ptr %[[VAR]], align 4
|
|
// OGCG: store i32 %[[ELE_0]], ptr %[[ARR]], align 4
|
|
// OGCG: %[[ELE_1:.*]] = getelementptr inbounds i32, ptr %[[ARR]], i64 1
|
|
// OGCG: store i32 5, ptr %[[ELE_1:.*]], align 4
|
|
|
|
void func7() {
|
|
int* arr[1] = {};
|
|
}
|
|
|
|
// CIR: %[[ARR:.*]] = cir.alloca !cir.array<!cir.ptr<!s32i> x 1>, !cir.ptr<!cir.array<!cir.ptr<!s32i> x 1>>, ["arr", init]
|
|
// CIR: %[[CONST:.*]] = cir.get_global @[[FUNC7_ARR]] : !cir.ptr<!cir.array<!cir.ptr<!s32i> x 1>>
|
|
// CIR: cir.copy %[[CONST]] to %[[ARR]] : !cir.ptr<!cir.array<!cir.ptr<!s32i> x 1>>
|
|
|
|
// LLVM: define{{.*}} void @_Z5func7v(){{.*}}
|
|
// LLVM: %[[ARR:.*]] = alloca [1 x ptr], i64 1, align 8
|
|
// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %[[ARR]], ptr @[[FUNC7_ARR:.*]], i64 8, i1 false)
|
|
|
|
// OGCG: %[[ARR:.*]] = alloca [1 x ptr], align 8
|
|
// OGCG: call void @llvm.memset.p0.i64(ptr align 8 %[[ARR]], i8 0, i64 8, i1 false)
|
|
|
|
void func8(int arr[10]) {
|
|
int e = arr[0];
|
|
int e2 = arr[1];
|
|
}
|
|
|
|
// CIR: cir.func{{.*}} @_Z5func8Pi(%[[ARG:.*]]: !cir.ptr<!s32i>
|
|
// CIR: %[[ARR:.*]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["arr", init]
|
|
// CIR: %[[INIT:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["e", init]
|
|
// CIR: %[[INIT_2:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["e2", init]
|
|
// 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: %[[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: %[[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>
|
|
|
|
// LLVM: define{{.*}} void @_Z5func8Pi(ptr {{.*}} %[[ARG:.*]]){{.*}}
|
|
// LLVM: %[[ARR:.*]] = alloca ptr, i64 1, align 8
|
|
// LLVM: %[[INIT:.*]] = alloca i32, i64 1, align 4
|
|
// LLVM: %[[INIT_2:.*]] = alloca i32, i64 1, align 4
|
|
// LLVM: store ptr %[[ARG]], ptr %[[ARR]], align 8
|
|
// LLVM: %[[TMP_1:.*]] = load ptr, ptr %[[ARR]], align 8
|
|
// LLVM: %[[ELE_0:.*]] = getelementptr i32, ptr %[[TMP_1]], i64 0
|
|
// LLVM: %[[TMP_2:.*]] = load i32, ptr %[[ELE_0]], align 4
|
|
// LLVM: store i32 %[[TMP_2]], ptr %[[INIT]], align 4
|
|
// LLVM: %[[TMP_3:.*]] = load ptr, ptr %[[ARR]], align 8
|
|
// LLVM: %[[ELE_1:.*]] = getelementptr i32, ptr %[[TMP_3]], i64 1
|
|
// LLVM: %[[TMP_4:.*]] = load i32, ptr %[[ELE_1]], align 4
|
|
// LLVM: store i32 %[[TMP_4]], ptr %[[INIT_2]], align 4
|
|
|
|
// OGCG: %[[ARR:.*]] = alloca ptr, align 8
|
|
// OGCG: %[[INIT:.*]] = alloca i32, align 4
|
|
// OGCG: %[[INIT_2:.*]] = alloca i32, align 4
|
|
// OGCG: store ptr {{%.*}}, ptr %[[ARR]], align 8
|
|
// OGCG: %[[TMP_1:.*]] = load ptr, ptr %[[ARR]], align 8
|
|
// OGCG: %[[ELE_0:.*]] = getelementptr inbounds i32, ptr %[[TMP_1]], i64 0
|
|
// OGCG: %[[TMP_2:.*]] = load i32, ptr %[[ELE_0]], align 4
|
|
// OGCG: store i32 %[[TMP_2]], ptr %[[INIT]], align 4
|
|
// OGCG: %[[TMP_3:.*]] = load ptr, ptr %[[ARR]], align 8
|
|
// OGCG: %[[ELE_1:.*]] = getelementptr inbounds i32, ptr %[[TMP_3]], i64 1
|
|
// OGCG: %[[TMP_2:.*]] = load i32, ptr %[[ELE_1]], align 4
|
|
// OGCG: store i32 %[[TMP_2]], ptr %[[INIT_2]], align 4
|
|
|
|
void func9(int arr[10][5]) {
|
|
int e = arr[1][2];
|
|
}
|
|
|
|
// CIR: cir.func{{.*}} @_Z5func9PA5_i(%[[ARG:.*]]: !cir.ptr<!cir.array<!s32i x 5>>
|
|
// CIR: %[[ARR:.*]] = cir.alloca !cir.ptr<!cir.array<!s32i x 5>>, !cir.ptr<!cir.ptr<!cir.array<!s32i x 5>>>, ["arr", init]
|
|
// CIR: %[[INIT:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["e", init]
|
|
// 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: %[[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: %[[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>
|
|
|
|
// LLVM: define{{.*}} void @_Z5func9PA5_i(ptr {{.*}} %[[ARG:.*]]){{.*}}
|
|
// LLVM: %[[ARR:.*]] = alloca ptr, i64 1, align 8
|
|
// LLVM: %[[INIT:.*]] = alloca i32, i64 1, align 4
|
|
// LLVM: store ptr %[[ARG]], ptr %[[ARR]], align 8
|
|
// LLVM: %[[TMP_1:.*]] = load ptr, ptr %[[ARR]], align 8
|
|
// LLVM: %[[ARR_1:.*]] = getelementptr [5 x i32], ptr %[[TMP_1]], i64 1
|
|
// LLVM: %[[ARR_1_2:.*]] = getelementptr [5 x i32], ptr %[[ARR_1]], i32 0, i64 2
|
|
// LLVM: %[[TMP_2:.*]] = load i32, ptr %[[ARR_1_2]], align 4
|
|
// LLVM: store i32 %[[TMP_2]], ptr %[[INIT]], align 4
|
|
|
|
// OGCG: %[[ARR:.*]] = alloca ptr, align 8
|
|
// OGCG: %[[INIT:.*]] = alloca i32, align 4
|
|
// OGCG: store ptr {{%.*}}, ptr %[[ARR]], align 8
|
|
// OGCG: %[[TMP_1:.*]] = load ptr, ptr %[[ARR]], align 8
|
|
// OGCG: %[[ARR_1:.*]] = getelementptr inbounds [5 x i32], ptr %[[TMP_1]], i64 1
|
|
// OGCG: %[[ARR_1_2:.*]] = getelementptr inbounds [5 x i32], ptr %[[ARR_1]], i64 0, i64 2
|
|
// OGCG: %[[TMP_2:.*]] = load i32, ptr %[[ARR_1_2]], align 4
|
|
// OGCG: store i32 %[[TMP_2]], ptr %[[INIT]], align 4
|
|
|
|
void func10(int *a) {
|
|
int e = a[5];
|
|
}
|
|
|
|
// CIR: cir.func{{.*}} @_Z6func10Pi(%[[ARG:.*]]: !cir.ptr<!s32i>
|
|
// CIR: %[[ARR:.*]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["a", init]
|
|
// CIR: %[[INIT:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["e", init]
|
|
// 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: %[[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>
|
|
|
|
// LLVM: define{{.*}} void @_Z6func10Pi(ptr {{.*}} %[[ARG:.*]]){{.*}} {
|
|
// LLVM: %[[ARR:.*]] = alloca ptr, i64 1, align 8
|
|
// LLVM: %[[INIT:.*]] = alloca i32, i64 1, align 4
|
|
// LLVM: store ptr %[[ARG]], ptr %[[ARR]], align 8
|
|
// LLVM: %[[TMP_1:.*]] = load ptr, ptr %[[ARR]], align 8
|
|
// LLVM: %[[ELE:.*]] = getelementptr i32, ptr %[[TMP_1]], i64 5
|
|
// LLVM: %[[TMP_2:.*]] = load i32, ptr %[[ELE]], align 4
|
|
// LLVM: store i32 %[[TMP_2]], ptr %[[INIT]], align 4
|
|
|
|
// OGCG: %[[ARR:.*]] = alloca ptr, align 8
|
|
// OGCG: %[[INIT:.*]] = alloca i32, align 4
|
|
// OGCG: store ptr {{%.*}}, ptr %[[ARR]], align 8
|
|
// OGCG: %[[TMP_1:.*]] = load ptr, ptr %[[ARR]], align 8
|
|
// OGCG: %[[ELE:.*]] = getelementptr inbounds i32, ptr %[[TMP_1]], i64 5
|
|
// OGCG: %[[TMP_2:.*]] = load i32, ptr %[[ELE]], align 4
|
|
// OGCG: store i32 %[[TMP_2]], ptr %[[INIT]], align 4
|
|
|
|
void func11() { int _Complex a[4]; }
|
|
|
|
// CIR: %[[ARR:.*]] = cir.alloca !cir.array<!cir.complex<!s32i> x 4>, !cir.ptr<!cir.array<!cir.complex<!s32i> x 4>>, ["a"]
|
|
|
|
// LLVM: %[[ARR:.*]] = alloca [4 x { i32, i32 }], i64 1, align 16
|
|
|
|
// OGCG: %[[ARR:.*]] = alloca [4 x { i32, i32 }], align 16
|
|
|
|
void func12() {
|
|
struct Point {
|
|
int x;
|
|
int y;
|
|
};
|
|
|
|
Point a[4];
|
|
}
|
|
|
|
// CIR: %[[ARR:.*]] = cir.alloca !cir.array<!rec_Point x 4>, !cir.ptr<!cir.array<!rec_Point x 4>>, ["a"]
|
|
|
|
// LLVM: %[[ARR:.*]] = alloca [4 x %struct.Point], i64 1, align 16
|
|
|
|
// OGCG: %[[ARR:.*]] = alloca [4 x %struct.Point], align 16
|
|
|
|
void array_with_complex_elements() {
|
|
_Complex float arr[2] = {{1.1f, 2.2f}, {3.3f, 4.4f}};
|
|
}
|
|
|
|
// CIR: %[[ARR_ADDR:.*]] = cir.alloca !cir.array<!cir.complex<!cir.float> x 2>, !cir.ptr<!cir.array<!cir.complex<!cir.float> x 2>>, ["arr", init]
|
|
// CIR: %[[CONST:.*]] = cir.get_global @[[COMPLEX_ARR]] : !cir.ptr<!cir.array<!cir.complex<!cir.float> x 2>>
|
|
// CIR: cir.copy %[[CONST]] to %[[ARR_ADDR]] : !cir.ptr<!cir.array<!cir.complex<!cir.float> x 2>>
|
|
|
|
// LLVM: %[[ARR_ADDR:.*]] = alloca [2 x { float, float }], i64 1, align 16
|
|
// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %[[ARR_ADDR]], ptr @[[COMPLEX_ARR:.*]], i64 16, i1 false)
|
|
|
|
// OGCG: %[[ARR_ADDR:.*]] = alloca [2 x { float, float }], align 16
|
|
// OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 16 %[[ARR_ADDR]], ptr align 16 @__const._Z27array_with_complex_elementsv.arr, i64 16, i1 false)
|
|
|
|
void boolean_index_access(int x) {
|
|
int arr[2] = { 1, 2 };
|
|
int n = arr[x > 4];
|
|
}
|
|
|
|
// CIR: %[[X_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init]
|
|
// CIR: %[[ARR_ADDR:.*]] = cir.alloca !cir.array<!s32i x 2>, !cir.ptr<!cir.array<!s32i x 2>>, ["arr", init]
|
|
// CIR: %[[N_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["n", init]
|
|
// CIR: %[[X:.*]] = cir.load{{.*}} %[[X_ADDR]] : !cir.ptr<!s32i>, !s32i
|
|
// CIR: %[[FOUR:.*]] = cir.const #cir.int<4> : !s32i
|
|
// CIR: %[[CMP:.*]] = cir.cmp gt %[[X]], %[[FOUR]] : !s32i
|
|
// CIR: %[[IDX:.*]] = cir.cast bool_to_int %[[CMP]] : !cir.bool -> !u64i
|
|
// CIR: %[[ELE:.*]] = cir.get_element %[[ARR_ADDR]][%[[IDX]] : !u64i] : !cir.ptr<!cir.array<!s32i x 2>> -> !cir.ptr<!s32i>
|
|
// CIR: %[[VAL:.*]] = cir.load{{.*}} %[[ELE]] : !cir.ptr<!s32i>, !s32i
|
|
// CIR: cir.store{{.*}} %[[VAL]], %[[N_ADDR]] : !s32i, !cir.ptr<!s32i>
|
|
|
|
// LLVM: %[[X_ADDR:.*]] = alloca i32
|
|
// LLVM: %[[ARR_ADDR:.*]] = alloca [2 x i32]
|
|
// LLVM: %[[N_ADDR:.*]] = alloca i32
|
|
// LLVM: %[[X:.*]] = load i32, ptr %[[X_ADDR]]
|
|
// LLVM: %[[CMP:.*]] = icmp sgt i32 %[[X]], 4
|
|
// LLVM: %[[IDX:.*]] = zext i1 %[[CMP]] to i64
|
|
// LLVM: %[[ELE:.*]] = getelementptr [2 x i32], ptr %[[ARR_ADDR]], i32 0, i64 %[[IDX]]
|
|
// LLVM: %[[VAL:.*]] = load i32, ptr %[[ELE]]
|
|
// LLVM: store i32 %[[VAL]], ptr %[[N_ADDR]]
|
|
|
|
// OGCG: %[[X_ADDR:.*]] = alloca i32
|
|
// OGCG: %[[ARR_ADDR:.*]] = alloca [2 x i32]
|
|
// OGCG: %[[N_ADDR:.*]] = alloca i32
|
|
// OGCG: %[[X:.*]] = load i32, ptr %[[X_ADDR]]
|
|
// OGCG: %[[CMP:.*]] = icmp sgt i32 %[[X]], 4
|
|
// OGCG: %[[IDX:.*]] = zext i1 %[[CMP]] to i64
|
|
// OGCG: %[[ELE:.*]] = getelementptr inbounds nuw [2 x i32], ptr %[[ARR_ADDR]], i64 0, i64 %[[IDX]]
|
|
// OGCG: %[[VAL:.*]] = load i32, ptr %[[ELE]]
|
|
// OGCG: store i32 %[[VAL]], ptr %[[N_ADDR]]
|
|
|
|
void bitint_index_access(_BitInt(7) i) {
|
|
int arr[10] = {};
|
|
int n = arr[i];
|
|
}
|
|
|
|
// A narrow signed _BitInt index must be sign-extended to pointer width before
|
|
// being used as a subscript.
|
|
|
|
// CIR: cir.func{{.*}} @_Z19bitint_index_accessDB7_
|
|
// CIR: %[[I_ADDR:.*]] = cir.alloca !cir.int<s, 7, bitint>, !cir.ptr<!cir.int<s, 7, bitint>>, ["i", init]
|
|
// CIR: %[[ARR_ADDR:.*]] = cir.alloca !cir.array<!s32i x 10>, !cir.ptr<!cir.array<!s32i x 10>>, ["arr", init]
|
|
// CIR: %[[N_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["n", init]
|
|
// CIR: %[[I:.*]] = cir.load{{.*}} %[[I_ADDR]] : !cir.ptr<!cir.int<s, 7, bitint>>, !cir.int<s, 7, bitint>
|
|
// CIR: %[[IDX:.*]] = cir.cast integral %[[I]] : !cir.int<s, 7, bitint> -> !s64i
|
|
// CIR: %[[ELE:.*]] = cir.get_element %[[ARR_ADDR]][%[[IDX]] : !s64i] : !cir.ptr<!cir.array<!s32i x 10>> -> !cir.ptr<!s32i>
|
|
// CIR: %[[VAL:.*]] = cir.load{{.*}} %[[ELE]] : !cir.ptr<!s32i>, !s32i
|
|
// CIR: cir.store{{.*}} %[[VAL]], %[[N_ADDR]] : !s32i, !cir.ptr<!s32i>
|
|
|
|
// LLVM: define{{.*}} @_Z19bitint_index_accessDB7_(i7 {{[^)]*}})
|
|
// LLVM: %[[I_ADDR:.*]] = alloca i7
|
|
// LLVM: %[[ARR_ADDR:.*]] = alloca [10 x i32]
|
|
// LLVM: %[[N_ADDR:.*]] = alloca i32
|
|
// LLVM: %[[I:.*]] = load i7, ptr %[[I_ADDR]]
|
|
// LLVM: %[[IDX:.*]] = sext i7 %[[I]] to i64
|
|
// LLVM: %[[ELE:.*]] = getelementptr [10 x i32], ptr %[[ARR_ADDR]], i32 0, i64 %[[IDX]]
|
|
// LLVM: %[[VAL:.*]] = load i32, ptr %[[ELE]]
|
|
// LLVM: store i32 %[[VAL]], ptr %[[N_ADDR]]
|
|
|
|
// OGCG: define{{.*}} @_Z19bitint_index_accessDB7_(i7 {{[^)]*}})
|
|
// OGCG: %[[I_ADDR:.*]] = alloca i8
|
|
// OGCG: %[[ARR_ADDR:.*]] = alloca [10 x i32]
|
|
// OGCG: %[[N_ADDR:.*]] = alloca i32
|
|
// OGCG: %[[I:.*]] = load i8, ptr %[[I_ADDR]]
|
|
// OGCG: %[[I_CAST:.*]] = trunc i8 %[[I]] to i7
|
|
// OGCG: %[[IDX:.*]] = sext i7 %[[I_CAST]] to i64
|
|
// OGCG: %[[ELE:.*]] = getelementptr inbounds [10 x i32], ptr %[[ARR_ADDR]], i64 0, i64 %[[IDX]]
|
|
// OGCG: %[[VAL:.*]] = load i32, ptr %[[ELE]]
|
|
// OGCG: store i32 %[[VAL]], ptr %[[N_ADDR]]
|
|
|
|
char access_last_element_of_huge_array() {
|
|
return huge[0x1FFFFFFFFFFFFFFEULL];
|
|
}
|
|
|
|
// 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: %[[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
|
|
|
|
// LLVM: define{{.*}} @_Z33access_last_element_of_huge_arrayv()
|
|
// LLVM: load i8, ptr getelementptr inbounds nuw (i8, ptr @huge, i64 2305843009213693950)
|
|
|
|
// OGCG: define{{.*}} @_Z33access_last_element_of_huge_arrayv()
|
|
// OGCG: load i8, ptr getelementptr inbounds nuw (i8, ptr @huge, i64 2305843009213693950)
|