Skip to content

Commit fba70e2

Browse files
gitoleglanza
authored andcommitted
[CIR][Codegen] supports aarch64_be (#864)
This PR adds aarch64 big endian support. Basically the support for aarch64_be itself is expressed only in two extra cases for the switch statement and changes in the `CIRDataLayout` are needed to prove that we really support big endian. Hence the idea for the test - I think the best way for proof is something connected with bit-fields, so we compare the results of the original codegen and ours.
1 parent 572ecf7 commit fba70e2

File tree

5 files changed

+73
-4
lines changed

5 files changed

+73
-4
lines changed

clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#ifndef LLVM_CLANG_CIR_DIALECT_IR_CIRDATALAYOUT_H
1313
#define LLVM_CLANG_CIR_DIALECT_IR_CIRDATALAYOUT_H
1414

15+
#include "mlir/Dialect/DLTI/DLTI.h"
1516
#include "mlir/IR/BuiltinOps.h"
1617
#include "clang/CIR/Dialect/IR/CIRTypes.h"
1718
#include "llvm/IR/DataLayout.h"
@@ -41,7 +42,7 @@ class CIRDataLayout {
4142
CIRDataLayout(mlir::ModuleOp modOp);
4243

4344
/// Parse a data layout string (with fallback to default values).
44-
void reset();
45+
void reset(mlir::DataLayoutSpecInterface spec);
4546

4647
// Free all internal data structures.
4748
void clear();

clang/lib/CIR/CodeGen/TargetInfo.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,8 @@ const TargetCIRGenInfo &CIRGenModule::getTargetCIRGenInfo() {
588588
switch (Triple.getArch()) {
589589
default:
590590
assert(false && "Target not yet supported!");
591+
592+
case llvm::Triple::aarch64_be:
591593
case llvm::Triple::aarch64: {
592594
AArch64ABIInfo::ABIKind Kind = AArch64ABIInfo::AAPCS;
593595
assert(getTarget().getABI() == "aapcs" ||

clang/lib/CIR/Dialect/IR/CIRDataLayout.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,24 @@ class StructLayoutMap {
112112

113113
} // namespace
114114

115-
CIRDataLayout::CIRDataLayout(mlir::ModuleOp modOp) : layout{modOp} { reset(); }
115+
CIRDataLayout::CIRDataLayout(mlir::ModuleOp modOp) : layout{modOp} {
116+
reset(modOp.getDataLayoutSpec());
117+
}
116118

117-
void CIRDataLayout::reset() {
119+
void CIRDataLayout::reset(mlir::DataLayoutSpecInterface spec) {
118120
clear();
119121

120-
LayoutMap = nullptr;
121122
bigEndian = false;
123+
if (spec) {
124+
auto key = mlir::StringAttr::get(
125+
spec.getContext(), mlir::DLTIDialect::kDataLayoutEndiannessKey);
126+
if (auto entry = spec.getSpecForIdentifier(key))
127+
if (auto str = llvm::dyn_cast<mlir::StringAttr>(entry.getValue()))
128+
bigEndian = str == mlir::DLTIDialect::kDataLayoutEndiannessBig;
129+
}
130+
131+
LayoutMap = nullptr;
132+
122133
// ManglingMode = MM_None;
123134
// NonIntegralAddressSpaces.clear();
124135
StructAlignment =

clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ createTargetLoweringInfo(LowerModule &LM) {
6262
const llvm::Triple &Triple = Target.getTriple();
6363

6464
switch (Triple.getArch()) {
65+
case llvm::Triple::aarch64_be:
6566
case llvm::Triple::aarch64: {
6667
AArch64ABIKind Kind = AArch64ABIKind::AAPCS;
6768
if (Target.getABI() == "darwinpcs")

clang/test/CIR/CodeGen/bitfields_be.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// RUN: %clang_cc1 -triple aarch64_be-unknown-linux-gnu -emit-llvm %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s -check-prefix=LLVM
3+
4+
// RUN: %clang_cc1 -triple aarch64_be-unknown-linux-gnu -fclangir -emit-llvm %s -o %t1.cir
5+
// RUN: FileCheck --input-file=%t1.cir %s
6+
7+
typedef struct {
8+
int a : 4;
9+
int b : 11;
10+
int c : 17;
11+
} S;
12+
13+
void init(S* s) {
14+
s->a = -4;
15+
s->b = 42;
16+
s->c = -12345;
17+
}
18+
19+
// field 'a'
20+
// LLVM: %[[PTR0:.*]] = load ptr
21+
// CHECK: %[[PTR0:.*]] = load ptr
22+
// LLVM: %[[VAL0:.*]] = load i32, ptr %[[PTR0]]
23+
// CHECK: %[[VAL0:.*]] = load i32, ptr %[[PTR0]]
24+
// LLVM: %[[AND0:.*]] = and i32 %[[VAL0]], 268435455
25+
// CHECK: %[[AND0:.*]] = and i32 %[[VAL0]], 268435455
26+
// LLVM: %[[OR0:.*]] = or i32 %[[AND0]], -1073741824
27+
// CHECK: %[[OR0:.*]] = or i32 %[[AND0]], -1073741824
28+
// LLVM: store i32 %[[OR0]], ptr %[[PTR0]]
29+
// CHECK: store i32 %[[OR0]], ptr %[[PTR0]]
30+
31+
// field 'b'
32+
// LLVM: %[[PTR1:.*]] = load ptr
33+
// CHECK: %[[PTR1:.*]] = load ptr
34+
// LLVM: %[[VAL1:.*]] = load i32, ptr %[[PTR1]]
35+
// CHECK: %[[VAL1:.*]] = load i32, ptr %[[PTR1]]
36+
// LLVM: %[[AND1:.*]] = and i32 %[[VAL1]], -268304385
37+
// CHECK: %[[AND1:.*]] = and i32 %[[VAL1]], -268304385
38+
// LLVM: %[[OR1:.*]] = or i32 %[[AND1]], 5505024
39+
// CHECK: %[[OR1:.*]] = or i32 %[[AND1]], 5505024
40+
// LLVM: store i32 %[[OR1]], ptr %[[PTR1]]
41+
// CHECK: store i32 %[[OR1]], ptr %[[PTR1]]
42+
43+
// field 'c'
44+
// LLVM: %[[PTR2:.*]] = load ptr
45+
// CHECK: %[[PTR2:.*]] = load ptr
46+
// LLVM: %[[VAL2:.*]] = load i32, ptr %[[PTR2]]
47+
// CHECK: %[[VAL2:.*]] = load i32, ptr %[[PTR2]]
48+
// LLVM: %[[AND2:.*]] = and i32 %[[VAL2]], -131072
49+
// CHECK: %[[AND2:.*]] = and i32 %[[VAL2]], -131072
50+
// LLVM: %[[OR2:.*]] = or i32 %[[AND2]], 118727
51+
// CHECK: %[[OR2:.*]] = or i32 %[[AND2]], 118727
52+
// LLVM: store i32 %[[OR2]], ptr %[[PTR2]]
53+
// CHECK: store i32 %[[OR2]], ptr %[[PTR2]]
54+

0 commit comments

Comments
 (0)