Skip to content

Commit 16e2250

Browse files
authored
[CIR] Fix parsing of a generic TBAAAttr (#1846)
This PR fixes an issue when parsing `TBAAAttr` derived attributes. The root cause of the issue is that the RTTI system is not capable of downcasting `mlir::Attribute` to the `BaseType`, which is `cir::TBAAAttr`, since each attribute has its unique TypeID. As such, the default generated parser fails, because the `dyn_cast` to `cir::TBAAAttr` fails (this happens for example with the attached test case). If anyone can think of a solution that wouldn't require explicitly listing all the attributes I'm happy to modify it.
1 parent ff4c1fd commit 16e2250

File tree

5 files changed

+89
-13
lines changed

5 files changed

+89
-13
lines changed

clang/include/clang/CIR/Dialect/IR/CIRAttrConstraints.td

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,32 @@ def CIR_AnyIntOrFloatAttr : AnyAttrOf<[CIR_AnyIntAttr, CIR_AnyFPAttr],
4545
def CIR_IntArrayAttr : TypedArrayAttrBase<CIR_AnyIntAttr,
4646
"integer array attribute">;
4747

48+
//===----------------------------------------------------------------------===//
49+
// TBAAAttr constraints
50+
//===----------------------------------------------------------------------===//
51+
52+
def CIR_TBAAConstraint
53+
: CIR_AttrConstraint<"::cir::TBAAAttr", "base attribute for TBAA">;
54+
def CIR_TBAAOmnipotentCharConstraint
55+
: CIR_AttrConstraint<"::cir::TBAAOmnipotentCharAttr", "Omnipotent char type">;
56+
def CIR_TBAAVTablePointerConstraint
57+
: CIR_AttrConstraint<"::cir::TBAAVTablePointerAttr", "VTable pointer type">;
58+
def CIR_TBAAScalarConstraint
59+
: CIR_AttrConstraint<"::cir::TBAAScalarAttr", "Scalar type with identifier">;
60+
def CIR_TBAAStructConstraint
61+
: CIR_AttrConstraint<"::cir::TBAAStructAttr", "Struct type">;
62+
def CIR_TBAATagConstraint
63+
: CIR_AttrConstraint<"::cir::TBAATagAttr", "Member of a TBAA struct type">;
64+
65+
def CIR_AnyTBAAAttr : AnyAttrOf<[
66+
CIR_TBAAConstraint,
67+
CIR_TBAAOmnipotentCharConstraint,
68+
CIR_TBAAVTablePointerConstraint,
69+
CIR_TBAAScalarConstraint,
70+
CIR_TBAAStructConstraint,
71+
CIR_TBAATagConstraint
72+
]> {
73+
string cppType = "::mlir::Attribute";
74+
}
75+
4876
#endif // CLANG_CIR_DIALECT_IR_CIRATTRCONSTRAINTS_TD

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4709,7 +4709,7 @@ def CIR_CopyOp : CIR_Op<"copy",[
47094709
let arguments = (ins Arg<CIR_PointerType, "", [MemWrite]>:$dst,
47104710
Arg<CIR_PointerType, "", [MemRead]>:$src,
47114711
UnitAttr:$is_volatile,
4712-
OptionalAttr<CIR_TBAAAttr>:$tbaa);
4712+
OptionalAttr<CIR_AnyTBAAAttr>:$tbaa);
47134713
let summary = "Copies contents from a CIR pointer to another";
47144714
let description = [{
47154715
Given two CIR pointers, `src` and `dst`, `cir.copy` will copy the memory

clang/include/clang/CIR/Dialect/IR/CIRTBAAAttrs.td

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#ifndef CLANG_CIR_DIALECT_IR_CIRTBAAATTRS_TD
1414
#define CLANG_CIR_DIALECT_IR_CIRTBAAATTRS_TD
1515

16+
include "clang/CIR/Dialect/IR/CIRAttrConstraints.td"
1617
include "clang/CIR/Dialect/IR/CIRTypes.td"
1718

1819
//===----------------------------------------------------------------------===//
@@ -91,8 +92,8 @@ def CIR_TBAAScalarAttr : CIR_TBAAAttrCase< "TBAAScalar", "tbaa_scalar"> {
9192
}
9293

9394
def CIR_TBAATagAttr : CIR_TBAAAttrCase<"TBAATag", "tbaa_tag"> {
94-
let parameters = (ins CIR_TBAAAttr
95-
: $base, CIR_TBAAAttr
95+
let parameters = (ins CIR_AnyTBAAAttr
96+
: $base, CIR_AnyTBAAAttr
9697
: $access, "int64_t"
9798
: $offset);
9899

@@ -101,7 +102,7 @@ def CIR_TBAATagAttr : CIR_TBAAAttrCase<"TBAATag", "tbaa_tag"> {
101102

102103
def CIR_TBAAMemberAttr : CIR_Attr<"TBAAMember", "tbaa_member"> {
103104
let summary = "Attribute representing a member of a TBAA structured type.";
104-
let parameters = (ins "TBAAAttr":$type_desc,
105+
let parameters = (ins CIR_AnyTBAAAttr:$type_desc,
105106
"int64_t":$offset);
106107
let description = [{
107108
Define a TBAA struct attribute.
@@ -170,13 +171,4 @@ def CIR_TBAAStructAttr : CIR_TBAAAttrCase<"TBAAStruct", "tbaa_struct"> {
170171
let assemblyFormat = "`<` struct(params) `>`";
171172
}
172173

173-
def CIR_AnyTBAAAttr : AnyAttrOf<[
174-
CIR_TBAAAttr,
175-
CIR_TBAAOmnipotentCharAttr,
176-
CIR_TBAAVTablePointerAttr,
177-
CIR_TBAAScalarAttr,
178-
CIR_TBAAStructAttr,
179-
CIR_TBAATagAttr
180-
]>;
181-
182174
#endif // CLANG_CIR_DIALECT_IR_CIRTBAAATTRS_TD

clang/test/CIR/IR/invalid.cir

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1630,3 +1630,31 @@ cir.func @invalidConditionTerminator (%arg0 : !cir.bool) -> !cir.void {
16301630
}
16311631
cir.return
16321632
}
1633+
1634+
// -----
1635+
1636+
!s16i = !cir.int<s, 16>
1637+
!s32i = !cir.int<s, 32>
1638+
#fn_attr = #cir<extra({nothrow = #cir.nothrow, uwtable = #cir.uwtable<async>})>
1639+
!rec_S = !cir.record<struct "S" {!s16i} #cir.record.decl.ast>
1640+
#tbaa_scalar = #cir.tbaa_scalar<id = "short", type = !s16i>
1641+
// expected-error @below {{invalid kind of attribute specified}}
1642+
// expected-error @below {{failed to parse CIR_TBAAStructAttr parameter 'members'}}
1643+
#tbaa_struct = #cir.tbaa_struct<id = "S", members = {#cir.uwtable<async>}>
1644+
#tbaa_tag = #cir.tbaa_tag<base = #tbaa_struct, access = #tbaa_scalar, offset = 0>
1645+
cir.global external dso_local @glob = #cir.zero : !rec_S {alignment = 2 : i64}
1646+
cir.func dso_local @main() -> !s32i extra(#fn_attr) {
1647+
%0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"] {alignment = 4 : i64}
1648+
%1 = cir.const #cir.int<0> : !s32i
1649+
%2 = cir.cast(integral, %1 : !s32i), !s16i
1650+
%3 = cir.get_global @glob : !cir.ptr<!rec_S>
1651+
%4 = cir.get_member %3[0] {name = "i"} : !cir.ptr<!rec_S> -> !cir.ptr<!s16i>
1652+
cir.store align(2) %2, %4 : !s16i, !cir.ptr<!s16i> tbaa(#tbaa_tag)
1653+
%5 = cir.get_global @glob : !cir.ptr<!rec_S>
1654+
%6 = cir.get_member %5[0] {name = "i"} : !cir.ptr<!rec_S> -> !cir.ptr<!s16i>
1655+
%7 = cir.load align(2) %6 : !cir.ptr<!s16i>, !s16i tbaa(#tbaa_tag)
1656+
%8 = cir.cast(integral, %7 : !s16i), !s32i
1657+
cir.store %8, %0 : !s32i, !cir.ptr<!s32i>
1658+
%9 = cir.load %0 : !cir.ptr<!s32i>, !s32i
1659+
cir.return %9 : !s32i
1660+
}

clang/test/CIR/IR/tbaa-parse.cir

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: cir-opt %s -o - | FileCheck %s
2+
3+
!s16i = !cir.int<s, 16>
4+
!s32i = !cir.int<s, 32>
5+
#fn_attr = #cir<extra({nothrow = #cir.nothrow, uwtable = #cir.uwtable<async>})>
6+
!rec_S = !cir.record<struct "S" {!s16i} #cir.record.decl.ast>
7+
// CHECK: #tbaa_scalar = #cir.tbaa_scalar<id = "short", type = !s16i>
8+
// CHECK: #tbaa_struct = #cir.tbaa_struct<id = "S", members = {<#tbaa_scalar, 0>}>
9+
// CHECK: #tbaa_tag = #cir.tbaa_tag<base = #tbaa_struct, access = #tbaa_scalar, offset = 0>
10+
#tbaa_scalar = #cir.tbaa_scalar<id = "short", type = !s16i>
11+
#tbaa_struct = #cir.tbaa_struct<id = "S", members = {<#tbaa_scalar, 0>}>
12+
#tbaa_tag = #cir.tbaa_tag<base = #tbaa_struct, access = #tbaa_scalar, offset = 0>
13+
cir.global external dso_local @glob = #cir.zero : !rec_S {alignment = 2 : i64}
14+
cir.func dso_local @main() -> !s32i extra(#fn_attr) {
15+
%0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"] {alignment = 4 : i64}
16+
%1 = cir.const #cir.int<0> : !s32i
17+
%2 = cir.cast(integral, %1 : !s32i), !s16i
18+
%3 = cir.get_global @glob : !cir.ptr<!rec_S>
19+
%4 = cir.get_member %3[0] {name = "i"} : !cir.ptr<!rec_S> -> !cir.ptr<!s16i>
20+
cir.store align(2) %2, %4 : !s16i, !cir.ptr<!s16i> tbaa(#tbaa_tag)
21+
%5 = cir.get_global @glob : !cir.ptr<!rec_S>
22+
%6 = cir.get_member %5[0] {name = "i"} : !cir.ptr<!rec_S> -> !cir.ptr<!s16i>
23+
%7 = cir.load align(2) %6 : !cir.ptr<!s16i>, !s16i tbaa(#tbaa_tag)
24+
%8 = cir.cast(integral, %7 : !s16i), !s32i
25+
cir.store %8, %0 : !s32i, !cir.ptr<!s32i>
26+
%9 = cir.load %0 : !cir.ptr<!s32i>, !s32i
27+
cir.return %9 : !s32i
28+
}

0 commit comments

Comments
 (0)