Skip to content

Commit c02095c

Browse files
sitio-coutolanza
authored andcommitted
[CIR][Lowering][Bugfix] Fix GetMemberOp lowering (llvm#273)
The wrong element type was being passed to LLVM's GEP op, generating an invalid IR. Tests were also updated to properly validate the `llvm.getelementptr` element type. Fixes llvm#272
1 parent a678df3 commit c02095c

File tree

8 files changed

+41
-65
lines changed

8 files changed

+41
-65
lines changed

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -1773,8 +1773,7 @@ class CIRGetMemberOpLowering
17731773
// Since the base address is a pointer to an aggregate, the first offset
17741774
// is always zero. The second offset tell us which member it will access.
17751775
llvm::SmallVector<mlir::LLVM::GEPArg, 2> offset{0, op.getIndex()};
1776-
const auto elementTy =
1777-
getTypeConverter()->convertType(structTy.getMembers()[op.getIndex()]);
1776+
const auto elementTy = getTypeConverter()->convertType(structTy);
17781777
rewriter.replaceOpWithNewOp<mlir::LLVM::GEPOp>(op, llResTy, elementTy,
17791778
adaptor.getAddr(), offset);
17801779
return mlir::success();

clang/test/CIR/Lowering/cast.cir

+20-34
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
// RUN: cir-opt %s -cir-to-llvm -o - | FileCheck %s -check-prefix=MLIR
2-
// RUN: cir-translate %s -cir-to-llvmir | FileCheck %s -check-prefix=LLVM
1+
// RUN: cir-opt %s -cir-to-llvm -o %t.cir
2+
// RUN: FileCheck %s --input-file=%t.cir
3+
34
!s16i = !cir.int<s, 16>
45
!s32i = !cir.int<s, 32>
56
!s64i = !cir.int<s, 64>
@@ -9,27 +10,8 @@
910
!u64i = !cir.int<u, 64>
1011

1112
module {
12-
cir.func @foo(%arg0: !s32i) -> !s32i {
13-
%4 = cir.cast(int_to_bool, %arg0 : !s32i), !cir.bool
14-
cir.return %arg0 : !s32i
15-
}
16-
17-
// MLIR: llvm.func @foo(%arg0: i32) -> i32
18-
// MLIR-NEXT: [[v0:%[0-9]]] = llvm.mlir.constant(0 : i32) : i32
19-
// MLIR-NEXT: [[v1:%[0-9]]] = llvm.icmp "ne" %arg0, %0 : i32
20-
// MLIR-NEXT: [[v2:%[0-9]]] = llvm.zext %1 : i1 to i8
21-
// MLIR-NEXT: llvm.return %arg0 : i32
22-
// MLIR-NEXT: }
23-
24-
25-
// LLVM: define i32 @foo(i32 %0)
26-
// LLVM-NEXT: %2 = icmp ne i32 %0, 0
27-
// LLVM-NEXT: %3 = zext i1 %2 to i8
28-
// LLVM-NEXT: ret i32 %0
29-
// LLVM-NEXT: }
30-
3113
cir.func @cStyleCasts(%arg0: !u32i, %arg1: !s32i, %arg2: f32) -> !s32i {
32-
// MLIR: llvm.func @cStyleCasts
14+
// CHECK: llvm.func @cStyleCasts
3315
%0 = cir.alloca !u32i, cir.ptr <!u32i>, ["x1", init] {alignment = 4 : i64}
3416
%1 = cir.alloca !s32i, cir.ptr <!s32i>, ["x2", init] {alignment = 4 : i64}
3517
%20 = cir.alloca !s16i, cir.ptr <!s16i>, ["x4", init] {alignment = 2 : i64}
@@ -46,47 +28,51 @@ module {
4628
// Integer casts.
4729
%9 = cir.load %0 : cir.ptr <!u32i>, !u32i
4830
%10 = cir.cast(integral, %9 : !u32i), !s8i
49-
// MLIR: %{{[0-9]+}} = llvm.trunc %{{[0-9]+}} : i32 to i8
31+
// CHECK: %{{[0-9]+}} = llvm.trunc %{{[0-9]+}} : i32 to i8
5032
cir.store %10, %3 : !s8i, cir.ptr <!s8i>
5133
%11 = cir.load %1 : cir.ptr <!s32i>, !s32i
5234
%12 = cir.cast(integral, %11 : !s32i), !s16i
53-
// MLIR: %{{[0-9]+}} = llvm.trunc %{{[0-9]+}} : i32 to i16
35+
// CHECK: %{{[0-9]+}} = llvm.trunc %{{[0-9]+}} : i32 to i16
5436
cir.store %12, %4 : !s16i, cir.ptr <!s16i>
5537
%13 = cir.load %0 : cir.ptr <!u32i>, !u32i
5638
%14 = cir.cast(integral, %13 : !u32i), !s64i
57-
// MLIR: %{{[0-9]+}} = llvm.zext %{{[0-9]+}} : i32 to i64
39+
// CHECK: %{{[0-9]+}} = llvm.zext %{{[0-9]+}} : i32 to i64
5840
cir.store %14, %5 : !s64i, cir.ptr <!s64i>
5941
%15 = cir.load %1 : cir.ptr <!s32i>, !s32i
6042
%16 = cir.cast(integral, %15 : !s32i), !s64i
61-
// MLIR: %{{[0-9]+}} = llvm.sext %{{[0-9]+}} : i32 to i64
43+
// CHECK: %{{[0-9]+}} = llvm.sext %{{[0-9]+}} : i32 to i64
6244
%30 = cir.cast(integral, %arg1 : !s32i), !u32i
6345
// Should not produce a cast.
6446
%32 = cir.cast(integral, %arg0 : !u32i), !s32i
6547
// Should not produce a cast.
6648
%21 = cir.load %20 : cir.ptr <!s16i>, !s16i
6749
%22 = cir.cast(integral, %21 : !s16i), !u64i
68-
// MLIR: %[[TMP:[0-9]+]] = llvm.sext %{{[0-9]+}} : i16 to i64
50+
// CHECK: %[[TMP:[0-9]+]] = llvm.sext %{{[0-9]+}} : i16 to i64
51+
%33 = cir.cast(int_to_bool, %arg1 : !s32i), !cir.bool
52+
// CHECK: %[[#ZERO:]] = llvm.mlir.constant(0 : i32) : i32
53+
// CHECK: %[[#CMP:]] = llvm.icmp "ne" %arg1, %[[#ZERO]] : i32
54+
// CHECK: %{{.+}} = llvm.zext %[[#CMP]] : i1 to i8
6955

7056
// Pointer casts.
7157
cir.store %16, %6 : !s64i, cir.ptr <!s64i>
7258
%17 = cir.cast(array_to_ptrdecay, %7 : !cir.ptr<!cir.array<!s32i x 3>>), !cir.ptr<!s32i>
7359
cir.store %17, %8 : !cir.ptr<!s32i>, cir.ptr <!cir.ptr<!s32i>>
74-
// MLIR: %{{[0-9]+}} = llvm.getelementptr %{{[0-9]+}}[0] : (!llvm.ptr) -> !llvm.ptr
60+
// CHECK: %{{[0-9]+}} = llvm.getelementptr %{{[0-9]+}}[0] : (!llvm.ptr) -> !llvm.ptr, i32
7561
%23 = cir.cast(int_to_ptr, %22 : !u64i), !cir.ptr<!u8i>
76-
// MLIR: %[[TMP2:[0-9]+]] = llvm.inttoptr %[[TMP]] : i64 to !llvm.ptr
62+
// CHECK: %[[TMP2:[0-9]+]] = llvm.inttoptr %[[TMP]] : i64 to !llvm.ptr
7763
%24 = cir.cast(ptr_to_int, %23 : !cir.ptr<!u8i>), !s32i
78-
// MLIR: %{{[0-9]+}} = llvm.ptrtoint %[[TMP2]] : !llvm.ptr to i32
64+
// CHECK: %{{[0-9]+}} = llvm.ptrtoint %[[TMP2]] : !llvm.ptr to i32
7965
%29 = cir.cast(ptr_to_bool, %23 : !cir.ptr<!u8i>), !cir.bool
8066

8167
// Floating point casts.
8268
%25 = cir.cast(int_to_float, %arg1 : !s32i), f32
83-
// MLIR: %{{.+}} = llvm.sitofp %{{.+}} : i32 to f32
69+
// CHECK: %{{.+}} = llvm.sitofp %{{.+}} : i32 to f32
8470
%26 = cir.cast(int_to_float, %arg0 : !u32i), f32
85-
// MLIR: %{{.+}} = llvm.uitofp %{{.+}} : i32 to f32
71+
// CHECK: %{{.+}} = llvm.uitofp %{{.+}} : i32 to f32
8672
%27 = cir.cast(float_to_int, %arg2 : f32), !s32i
87-
// MLIR: %{{.+}} = llvm.fptosi %{{.+}} : f32 to i32
73+
// CHECK: %{{.+}} = llvm.fptosi %{{.+}} : f32 to i32
8874
%28 = cir.cast(float_to_int, %arg2 : f32), !u32i
89-
// MLIR: %{{.+}} = llvm.fptoui %{{.+}} : f32 to i32
75+
// CHECK: %{{.+}} = llvm.fptoui %{{.+}} : f32 to i32
9076
%18 = cir.const(#cir.int<0> : !s32i) : !s32i
9177

9278
cir.store %18, %2 : !s32i, cir.ptr <!s32i>

clang/test/CIR/Lowering/dot.cir

+2-2
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,11 @@ module {
9797
// MLIR-NEXT: ^bb5: // pred: ^bb3
9898
// MLIR-NEXT: %22 = llvm.load %1 : !llvm.ptr -> !llvm.ptr
9999
// MLIR-NEXT: %23 = llvm.load %12 : !llvm.ptr -> i32
100-
// MLIR-NEXT: %24 = llvm.getelementptr %22[%23] : (!llvm.ptr, i32) -> !llvm.ptr
100+
// MLIR-NEXT: %24 = llvm.getelementptr %22[%23] : (!llvm.ptr, i32) -> !llvm.ptr, f64
101101
// MLIR-NEXT: %25 = llvm.load %24 : !llvm.ptr -> f64
102102
// MLIR-NEXT: %26 = llvm.load %3 : !llvm.ptr -> !llvm.ptr
103103
// MLIR-NEXT: %27 = llvm.load %12 : !llvm.ptr -> i32
104-
// MLIR-NEXT: %28 = llvm.getelementptr %26[%27] : (!llvm.ptr, i32) -> !llvm.ptr
104+
// MLIR-NEXT: %28 = llvm.getelementptr %26[%27] : (!llvm.ptr, i32) -> !llvm.ptr, f64
105105
// MLIR-NEXT: %29 = llvm.load %28 : !llvm.ptr -> f64
106106
// MLIR-NEXT: %30 = llvm.fmul %25, %29 : f64
107107
// MLIR-NEXT: %31 = llvm.load %9 : !llvm.ptr -> f64

clang/test/CIR/Lowering/globals.cir

+5-5
Original file line numberDiff line numberDiff line change
@@ -104,27 +104,27 @@ module {
104104
%5 = cir.get_global @string : cir.ptr <!cir.array<!s8i x 8>>
105105
%6 = cir.cast(array_to_ptrdecay, %5 : !cir.ptr<!cir.array<!s8i x 8>>), !cir.ptr<!s8i>
106106
// MLIR: %[[RES:[0-9]+]] = llvm.mlir.addressof @string : !llvm.ptr
107-
// MLIR: %{{[0-9]+}} = llvm.getelementptr %[[RES]][0] : (!llvm.ptr) -> !llvm.ptr
107+
// MLIR: %{{[0-9]+}} = llvm.getelementptr %[[RES]][0] : (!llvm.ptr) -> !llvm.ptr, i8
108108
cir.store %6, %0 : !cir.ptr<!s8i>, cir.ptr <!cir.ptr<!s8i>>
109109
%7 = cir.get_global @uint : cir.ptr <!cir.array<!u32i x 1>>
110110
%8 = cir.cast(array_to_ptrdecay, %7 : !cir.ptr<!cir.array<!u32i x 1>>), !cir.ptr<!u32i>
111111
// MLIR: %[[RES:[0-9]+]] = llvm.mlir.addressof @uint : !llvm.ptr
112-
// MLIR: %{{[0-9]+}} = llvm.getelementptr %[[RES]][0] : (!llvm.ptr) -> !llvm.ptr
112+
// MLIR: %{{[0-9]+}} = llvm.getelementptr %[[RES]][0] : (!llvm.ptr) -> !llvm.ptr, i32
113113
cir.store %8, %1 : !cir.ptr<!u32i>, cir.ptr <!cir.ptr<!u32i>>
114114
%9 = cir.get_global @sshort : cir.ptr <!cir.array<!s16i x 2>>
115115
%10 = cir.cast(array_to_ptrdecay, %9 : !cir.ptr<!cir.array<!s16i x 2>>), !cir.ptr<!s16i>
116116
// MLIR: %[[RES:[0-9]+]] = llvm.mlir.addressof @sshort : !llvm.ptr
117-
// MLIR: %{{[0-9]+}} = llvm.getelementptr %[[RES]][0] : (!llvm.ptr) -> !llvm.ptr
117+
// MLIR: %{{[0-9]+}} = llvm.getelementptr %[[RES]][0] : (!llvm.ptr) -> !llvm.ptr, i16
118118
cir.store %10, %2 : !cir.ptr<!s16i>, cir.ptr <!cir.ptr<!s16i>>
119119
%11 = cir.get_global @sint : cir.ptr <!cir.array<!s32i x 3>>
120120
%12 = cir.cast(array_to_ptrdecay, %11 : !cir.ptr<!cir.array<!s32i x 3>>), !cir.ptr<!s32i>
121121
// MLIR: %[[RES:[0-9]+]] = llvm.mlir.addressof @sint : !llvm.ptr
122-
// MLIR: %{{[0-9]+}} = llvm.getelementptr %[[RES]][0] : (!llvm.ptr) -> !llvm.ptr
122+
// MLIR: %{{[0-9]+}} = llvm.getelementptr %[[RES]][0] : (!llvm.ptr) -> !llvm.ptr, i32
123123
cir.store %12, %3 : !cir.ptr<!s32i>, cir.ptr <!cir.ptr<!s32i>>
124124
%13 = cir.get_global @ll : cir.ptr <!cir.array<!s64i x 4>>
125125
%14 = cir.cast(array_to_ptrdecay, %13 : !cir.ptr<!cir.array<!s64i x 4>>), !cir.ptr<!s64i>
126126
// MLIR: %[[RES:[0-9]+]] = llvm.mlir.addressof @ll : !llvm.ptr
127-
// MLIR: %{{[0-9]+}} = llvm.getelementptr %[[RES]][0] : (!llvm.ptr) -> !llvm.ptr
127+
// MLIR: %{{[0-9]+}} = llvm.getelementptr %[[RES]][0] : (!llvm.ptr) -> !llvm.ptr, i64
128128
cir.store %14, %4 : !cir.ptr<!s64i>, cir.ptr <!cir.ptr<!s64i>>
129129
cir.return
130130
}

clang/test/CIR/Lowering/hello.cir

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ module @"/tmp/test.raw" attributes {cir.lang = #cir.lang<c>, cir.sob = #cir.sign
2626
// CHECK: %0 = llvm.mlir.constant(1 : index) : i64
2727
// CHECK: %1 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i64) -> !llvm.ptr
2828
// CHECK: %2 = llvm.mlir.addressof @".str" : !llvm.ptr
29-
// CHECK: %3 = llvm.getelementptr %2[0] : (!llvm.ptr) -> !llvm.ptr
29+
// CHECK: %3 = llvm.getelementptr %2[0] : (!llvm.ptr) -> !llvm.ptr, i8
3030
// CHECK: %4 = llvm.call @printf(%3) : (!llvm.ptr) -> i32
3131
// CHECK: %5 = llvm.mlir.constant(0 : i32) : i32
3232
// CHECK: llvm.store %5, %1 : i32, !llvm.ptr

clang/test/CIR/Lowering/ptrstride.cir

+6-14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
// RUN: cir-opt %s -cir-to-llvm -o - | FileCheck %s -check-prefix=MLIR
2-
// RUN: cir-translate %s -cir-to-llvmir | FileCheck %s -check-prefix=LLVM
1+
// RUN: cir-opt %s -cir-to-llvm -o %t.cir
2+
// RUN: FileCheck %s --input-file=%t.cir -check-prefix=MLIR
3+
34
!s32i = !cir.int<s, 32>
45
module {
56
cir.func @f(%arg0: !cir.ptr<!s32i>) {
@@ -18,19 +19,10 @@ module {
1819
// MLIR-NEXT: %0 = llvm.mlir.constant(1 : index) : i64
1920
// MLIR-NEXT: %1 = llvm.alloca %0 x !llvm.ptr {alignment = 8 : i64} : (i64) -> !llvm.ptr
2021
// MLIR-NEXT: llvm.store %arg0, %1 : !llvm.ptr, !llvm.ptr
21-
// MLIR-NEXT: %2 = llvm.load %1 : !llvm.ptr
22+
// MLIR-NEXT: %2 = llvm.load %1 : !llvm.ptr -> !llvm.ptr
2223
// MLIR-NEXT: %3 = llvm.mlir.constant(1 : i32) : i32
23-
// MLIR-NEXT: %4 = llvm.getelementptr %2[%3] : (!llvm.ptr, i32) -> !llvm.ptr
24-
// MLIR-NEXT: %5 = llvm.load %4 : !llvm.ptr
24+
// MLIR-NEXT: %4 = llvm.getelementptr %2[%3] : (!llvm.ptr, i32) -> !llvm.ptr, i32
25+
// MLIR-NEXT: %5 = llvm.load %4 : !llvm.ptr -> i32
2526
// MLIR-NEXT: llvm.return
2627
// MLIR-NEXT: }
2728
// MLIR-NEXT: }
28-
29-
// LLVM: define void @f(ptr %0)
30-
// LLVM-NEXT: %2 = alloca ptr, i64 1, align 8
31-
// LLVM-NEXT: store ptr %0, ptr %2, align 8
32-
// LLVM-NEXT: %3 = load ptr, ptr %2, align 8
33-
// LLVM-NEXT: %4 = getelementptr i32, ptr %3, i32 1
34-
// LLVM-NEXT: %5 = load i32, ptr %4, align 4
35-
// LLVM-NEXT: ret void
36-
// LLVM-NEXT: }

clang/test/CIR/Lowering/struct.cir

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// RUN: cir-opt %s -cir-to-llvm -o %t.mlir
22
// RUN: FileCheck --input-file=%t.mlir %s
3-
// XFAIL: *
43

54
!s32i = !cir.int<s, 32>
65
!u8i = !cir.int<u, 8>
@@ -17,9 +16,9 @@ module {
1716
// CHECK: %[[#ARRSIZE:]] = llvm.mlir.constant(1 : index) : i64
1817
// CHECK: %[[#STRUCT:]] = llvm.alloca %[[#ARRSIZE]] x !llvm.struct<"struct.S", (i8, i32)>
1918
%3 = cir.get_member %1[0] {name = "c"} : !cir.ptr<!ty_22S22> -> !cir.ptr<!u8i>
20-
// CHECK: = llvm.getelementptr %[[#STRUCT]][0, 0] : (!llvm.ptr) -> !llvm.ptr
19+
// CHECK: = llvm.getelementptr %[[#STRUCT]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"struct.S", (i8, i32)>
2120
%5 = cir.get_member %1[1] {name = "i"} : !cir.ptr<!ty_22S22> -> !cir.ptr<!s32i>
22-
// CHECK: = llvm.getelementptr %[[#STRUCT]][0, 1] : (!llvm.ptr) -> !llvm.ptr
21+
// CHECK: = llvm.getelementptr %[[#STRUCT]][0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"struct.S", (i8, i32)>
2322
cir.return
2423
}
2524

clang/test/CIR/Lowering/variadics.cir

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,20 @@ module {
1616
cir.store %arg0, %0 : !s32i, cir.ptr <!s32i>
1717
%4 = cir.cast(array_to_ptrdecay, %2 : !cir.ptr<!cir.array<!ty_22__va_list_tag22 x 1>>), !cir.ptr<!ty_22__va_list_tag22>
1818
cir.va.start %4 : !cir.ptr<!ty_22__va_list_tag22>
19-
// MLIR: %{{[0-9]+}} = llvm.getelementptr %{{[0-9]+}}[0] : (!llvm.ptr) -> !llvm.ptr
19+
// MLIR: %{{[0-9]+}} = llvm.getelementptr %{{[0-9]+}}[0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"struct.__va_list_tag", (i32, i32, ptr, ptr)>
2020
// MLIR-NEXT: %{{[0-9]+}} = llvm.bitcast %{{[0-9]+}} : !llvm.ptr to !llvm.ptr
2121
// MLIR-NEXT: llvm.intr.vastart %{{[0-9]+}} : !llvm.ptr
2222
%5 = cir.cast(array_to_ptrdecay, %3 : !cir.ptr<!cir.array<!ty_22__va_list_tag22 x 1>>), !cir.ptr<!ty_22__va_list_tag22>
2323
%6 = cir.cast(array_to_ptrdecay, %2 : !cir.ptr<!cir.array<!ty_22__va_list_tag22 x 1>>), !cir.ptr<!ty_22__va_list_tag22>
2424
cir.va.copy %6 to %5 : !cir.ptr<!ty_22__va_list_tag22>, !cir.ptr<!ty_22__va_list_tag22>
25-
// MLIR: %{{[0-9]+}} = llvm.getelementptr %{{[0-9]+}}[0] : (!llvm.ptr) -> !llvm.ptr
26-
// MLIR-NEXT: %{{[0-9]+}} = llvm.getelementptr %{{[0-9]+}}[0] : (!llvm.ptr) -> !llvm.ptr
25+
// MLIR: %{{[0-9]+}} = llvm.getelementptr %{{[0-9]+}}[0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"struct.__va_list_tag", (i32, i32, ptr, ptr)>
26+
// MLIR-NEXT: %{{[0-9]+}} = llvm.getelementptr %{{[0-9]+}}[0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"struct.__va_list_tag", (i32, i32, ptr, ptr)>
2727
// MLIR-NEXT: %{{[0-9]+}} = llvm.bitcast %{{[0-9]+}} : !llvm.ptr to !llvm.ptr
2828
// MLIR-NEXT: %{{[0-9]+}} = llvm.bitcast %{{[0-9]+}} : !llvm.ptr to !llvm.ptr
2929
// MLIR-NEXT: llvm.intr.vacopy %13 to %{{[0-9]+}} : !llvm.ptr, !llvm.ptr
3030
%7 = cir.cast(array_to_ptrdecay, %2 : !cir.ptr<!cir.array<!ty_22__va_list_tag22 x 1>>), !cir.ptr<!ty_22__va_list_tag22>
3131
cir.va.end %7 : !cir.ptr<!ty_22__va_list_tag22>
32-
// MLIR: %{{[0-9]+}} = llvm.getelementptr %{{[0-9]+}}[0] : (!llvm.ptr) -> !llvm.ptr
32+
// MLIR: %{{[0-9]+}} = llvm.getelementptr %{{[0-9]+}}[0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"struct.__va_list_tag", (i32, i32, ptr, ptr)>
3333
// MLIR-NEXT: %{{[0-9]+}} = llvm.bitcast %{{[0-9]+}} : !llvm.ptr to !llvm.ptr
3434
// MLIR-NEXT: llvm.intr.vaend %{{[0-9]+}} : !llvm.ptr
3535
%8 = cir.const(#cir.int<0> : !s32i) : !s32i

0 commit comments

Comments
 (0)