diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h b/clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h index 98a926c19b2b..ffba7284988a 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h @@ -12,6 +12,7 @@ #ifndef LLVM_CLANG_CIR_DIALECT_IR_CIRDATALAYOUT_H #define LLVM_CLANG_CIR_DIALECT_IR_CIRDATALAYOUT_H +#include "mlir/Dialect/DLTI/DLTI.h" #include "mlir/IR/BuiltinOps.h" #include "clang/CIR/Dialect/IR/CIRTypes.h" #include "llvm/IR/DataLayout.h" @@ -41,7 +42,7 @@ class CIRDataLayout { CIRDataLayout(mlir::ModuleOp modOp); /// Parse a data layout string (with fallback to default values). - void reset(); + void reset(mlir::DataLayoutSpecInterface spec); // Free all internal data structures. void clear(); diff --git a/clang/lib/CIR/CodeGen/TargetInfo.cpp b/clang/lib/CIR/CodeGen/TargetInfo.cpp index ee39e1b28418..a802abe18313 100644 --- a/clang/lib/CIR/CodeGen/TargetInfo.cpp +++ b/clang/lib/CIR/CodeGen/TargetInfo.cpp @@ -588,6 +588,8 @@ const TargetCIRGenInfo &CIRGenModule::getTargetCIRGenInfo() { switch (Triple.getArch()) { default: assert(false && "Target not yet supported!"); + + case llvm::Triple::aarch64_be: case llvm::Triple::aarch64: { AArch64ABIInfo::ABIKind Kind = AArch64ABIInfo::AAPCS; assert(getTarget().getABI() == "aapcs" || diff --git a/clang/lib/CIR/Dialect/IR/CIRDataLayout.cpp b/clang/lib/CIR/Dialect/IR/CIRDataLayout.cpp index 12762b6c0aaf..13cf2f592db8 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDataLayout.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDataLayout.cpp @@ -110,13 +110,24 @@ class StructLayoutMap { } // namespace -CIRDataLayout::CIRDataLayout(mlir::ModuleOp modOp) : layout{modOp} { reset(); } +CIRDataLayout::CIRDataLayout(mlir::ModuleOp modOp) : layout{modOp} { + reset(modOp.getDataLayoutSpec()); +} -void CIRDataLayout::reset() { +void CIRDataLayout::reset(mlir::DataLayoutSpecInterface spec) { clear(); - LayoutMap = nullptr; bigEndian = false; + if (spec) { + auto key = mlir::StringAttr::get( + spec.getContext(), mlir::DLTIDialect::kDataLayoutEndiannessKey); + if (auto entry = spec.getSpecForIdentifier(key)) + if (auto str = llvm::dyn_cast(entry.getValue())) + bigEndian = str == mlir::DLTIDialect::kDataLayoutEndiannessBig; + } + + LayoutMap = nullptr; + // ManglingMode = MM_None; // NonIntegralAddressSpaces.clear(); StructAlignment = diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp index 086822ed4143..715a5f2470d7 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp @@ -62,6 +62,7 @@ createTargetLoweringInfo(LowerModule &LM) { const llvm::Triple &Triple = Target.getTriple(); switch (Triple.getArch()) { + case llvm::Triple::aarch64_be: case llvm::Triple::aarch64: { AArch64ABIKind Kind = AArch64ABIKind::AAPCS; if (Target.getABI() == "darwinpcs") diff --git a/clang/test/CIR/CodeGen/bitfields_be.c b/clang/test/CIR/CodeGen/bitfields_be.c new file mode 100644 index 000000000000..9063a33fdd8d --- /dev/null +++ b/clang/test/CIR/CodeGen/bitfields_be.c @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -triple aarch64_be-unknown-linux-gnu -emit-llvm %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s -check-prefix=LLVM + +// RUN: %clang_cc1 -triple aarch64_be-unknown-linux-gnu -fclangir -emit-llvm %s -o %t1.cir +// RUN: FileCheck --input-file=%t1.cir %s + +typedef struct { + int a : 4; + int b : 11; + int c : 17; +} S; + +void init(S* s) { + s->a = -4; + s->b = 42; + s->c = -12345; +} + +// field 'a' +// LLVM: %[[PTR0:.*]] = load ptr +// CHECK: %[[PTR0:.*]] = load ptr +// LLVM: %[[VAL0:.*]] = load i32, ptr %[[PTR0]] +// CHECK: %[[VAL0:.*]] = load i32, ptr %[[PTR0]] +// LLVM: %[[AND0:.*]] = and i32 %[[VAL0]], 268435455 +// CHECK: %[[AND0:.*]] = and i32 %[[VAL0]], 268435455 +// LLVM: %[[OR0:.*]] = or i32 %[[AND0]], -1073741824 +// CHECK: %[[OR0:.*]] = or i32 %[[AND0]], -1073741824 +// LLVM: store i32 %[[OR0]], ptr %[[PTR0]] +// CHECK: store i32 %[[OR0]], ptr %[[PTR0]] + +// field 'b' +// LLVM: %[[PTR1:.*]] = load ptr +// CHECK: %[[PTR1:.*]] = load ptr +// LLVM: %[[VAL1:.*]] = load i32, ptr %[[PTR1]] +// CHECK: %[[VAL1:.*]] = load i32, ptr %[[PTR1]] +// LLVM: %[[AND1:.*]] = and i32 %[[VAL1]], -268304385 +// CHECK: %[[AND1:.*]] = and i32 %[[VAL1]], -268304385 +// LLVM: %[[OR1:.*]] = or i32 %[[AND1]], 5505024 +// CHECK: %[[OR1:.*]] = or i32 %[[AND1]], 5505024 +// LLVM: store i32 %[[OR1]], ptr %[[PTR1]] +// CHECK: store i32 %[[OR1]], ptr %[[PTR1]] + +// field 'c' +// LLVM: %[[PTR2:.*]] = load ptr +// CHECK: %[[PTR2:.*]] = load ptr +// LLVM: %[[VAL2:.*]] = load i32, ptr %[[PTR2]] +// CHECK: %[[VAL2:.*]] = load i32, ptr %[[PTR2]] +// LLVM: %[[AND2:.*]] = and i32 %[[VAL2]], -131072 +// CHECK: %[[AND2:.*]] = and i32 %[[VAL2]], -131072 +// LLVM: %[[OR2:.*]] = or i32 %[[AND2]], 118727 +// CHECK: %[[OR2:.*]] = or i32 %[[AND2]], 118727 +// LLVM: store i32 %[[OR2]], ptr %[[PTR2]] +// CHECK: store i32 %[[OR2]], ptr %[[PTR2]] +