Skip to content

Commit 0a0c556

Browse files
authored
[CIR][CIRGen][Builtin][Type] Support for IEEE Quad (long double) added (in CIR + Direct to LLVM) (#966)
Fixes #931 Added type definition in CIRTypes.td, created appropriate functions for the same in CIRTypes.cpp like getPreferredAlignment, getPreferredAlignment, etc. Optionally added lowering in LowerToLLVM.cpp
1 parent 6d6cd8d commit 0a0c556

File tree

7 files changed

+72
-7
lines changed

7 files changed

+72
-7
lines changed

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,13 @@ def CIR_FP80 : CIR_FloatType<"FP80", "f80"> {
173173
}];
174174
}
175175

176+
def CIR_FP128 : CIR_FloatType<"FP128", "f128"> {
177+
let summary = "CIR type that represents IEEEquad 128-bit floating-point format";
178+
let description = [{
179+
Floating-point type that represents the IEEEquad 128-bit floating-point format.
180+
}];
181+
}
182+
176183
def CIR_LongDouble : CIR_FloatType<"LongDouble", "long_double"> {
177184
let summary = "CIR extended-precision float type";
178185
let description = [{
@@ -195,7 +202,7 @@ def CIR_LongDouble : CIR_FloatType<"LongDouble", "long_double"> {
195202

196203
// Constraints
197204

198-
def CIR_AnyFloat: AnyTypeOf<[CIR_Single, CIR_Double, CIR_FP80, CIR_LongDouble]>;
205+
def CIR_AnyFloat: AnyTypeOf<[CIR_Single, CIR_Double, CIR_FP80, CIR_FP128, CIR_LongDouble]>;
199206
def CIR_AnyIntOrFloat: AnyTypeOf<[CIR_AnyFloat, CIR_IntType]>;
200207

201208
//===----------------------------------------------------------------------===//

clang/lib/CIR/CodeGen/CIRGenBuilder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ class CIRGenBuilderTy : public CIRBaseBuilderTy {
402402
if (&format == &llvm::APFloat::x87DoubleExtended())
403403
return mlir::cir::LongDoubleType::get(getContext(), typeCache.FP80Ty);
404404
if (&format == &llvm::APFloat::IEEEquad())
405-
llvm_unreachable("NYI");
405+
return mlir::cir::LongDoubleType::get(getContext(), typeCache.FP128Ty);
406406
if (&format == &llvm::APFloat::PPCDoubleDouble())
407407
llvm_unreachable("NYI");
408408

clang/lib/CIR/CodeGen/CIRGenModule.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "mlir/IR/Verifier.h"
3636
#include "clang/AST/Expr.h"
3737
#include "clang/Basic/Cuda.h"
38+
#include "clang/CIR/Dialect/IR/CIRTypes.h"
3839
#include "clang/CIR/MissingFeatures.h"
3940

4041
#include "clang/AST/ASTConsumer.h"
@@ -74,8 +75,8 @@
7475
#include "llvm/Support/Casting.h"
7576
#include "llvm/Support/ErrorHandling.h"
7677
#include "llvm/Support/FileSystem.h"
77-
#include "llvm/Support/raw_ostream.h"
7878
#include "llvm/Support/TimeProfiler.h"
79+
#include "llvm/Support/raw_ostream.h"
7980

8081
#include <iterator>
8182
#include <numeric>
@@ -145,6 +146,7 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &context,
145146
FloatTy = ::mlir::cir::SingleType::get(builder.getContext());
146147
DoubleTy = ::mlir::cir::DoubleType::get(builder.getContext());
147148
FP80Ty = ::mlir::cir::FP80Type::get(builder.getContext());
149+
FP128Ty = ::mlir::cir::FP128Type::get(builder.getContext());
148150

149151
// TODO: PointerWidthInBits
150152
PointerAlignInBytes =
@@ -196,8 +198,7 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &context,
196198
theModule->setAttr("cir.sob",
197199
mlir::cir::SignedOverflowBehaviorAttr::get(&context, sob));
198200
auto lang = SourceLanguageAttr::get(&context, getCIRSourceLanguage());
199-
theModule->setAttr(
200-
"cir.lang", mlir::cir::LangAttr::get(&context, lang));
201+
theModule->setAttr("cir.lang", mlir::cir::LangAttr::get(&context, lang));
201202
theModule->setAttr("cir.triple", builder.getStringAttr(getTriple().str()));
202203
// Set the module name to be the name of the main file. TranslationUnitDecl
203204
// often contains invalid source locations and isn't a reliable source for the

clang/lib/CIR/CodeGen/CIRGenTypeCache.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
#include "mlir/IR/Types.h"
1818
#include "clang/AST/CharUnits.h"
1919
#include "clang/Basic/AddressSpaces.h"
20-
#include "clang/CIR/Dialect/IR/CIRTypes.h"
2120
#include "clang/CIR/Dialect/IR/CIRAttrs.h"
21+
#include "clang/CIR/Dialect/IR/CIRTypes.h"
2222
#include "clang/CIR/MissingFeatures.h"
2323

2424
namespace cir {
@@ -41,6 +41,7 @@ struct CIRGenTypeCache {
4141
mlir::cir::SingleType FloatTy;
4242
mlir::cir::DoubleType DoubleTy;
4343
mlir::cir::FP80Type FP80Ty;
44+
mlir::cir::FP128Type FP128Ty;
4445

4546
/// int
4647
mlir::Type UIntTy;

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

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,27 @@ FP80Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout,
763763
return 16;
764764
}
765765

766+
const llvm::fltSemantics &FP128Type::getFloatSemantics() const {
767+
return llvm::APFloat::IEEEquad();
768+
}
769+
770+
llvm::TypeSize
771+
FP128Type::getTypeSizeInBits(const mlir::DataLayout &dataLayout,
772+
mlir::DataLayoutEntryListRef params) const {
773+
return llvm::TypeSize::getFixed(16);
774+
}
775+
776+
uint64_t FP128Type::getABIAlignment(const mlir::DataLayout &dataLayout,
777+
mlir::DataLayoutEntryListRef params) const {
778+
return 16;
779+
}
780+
781+
uint64_t
782+
FP128Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout,
783+
::mlir::DataLayoutEntryListRef params) const {
784+
return 16;
785+
}
786+
766787
const llvm::fltSemantics &LongDoubleType::getFloatSemantics() const {
767788
return mlir::cast<mlir::cir::CIRFPTypeInterface>(getUnderlying())
768789
.getFloatSemantics();
@@ -792,7 +813,7 @@ uint64_t LongDoubleType::getPreferredAlignment(
792813
LogicalResult
793814
LongDoubleType::verify(function_ref<InFlightDiagnostic()> emitError,
794815
mlir::Type underlying) {
795-
if (!mlir::isa<DoubleType, FP80Type>(underlying)) {
816+
if (!mlir::isa<DoubleType, FP80Type, FP128Type>(underlying)) {
796817
emitError() << "invalid underlying type for long double";
797818
return failure();
798819
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4210,6 +4210,9 @@ void prepareTypeConverter(mlir::LLVMTypeConverter &converter,
42104210
converter.addConversion([&](mlir::cir::FP80Type type) -> mlir::Type {
42114211
return mlir::FloatType::getF80(type.getContext());
42124212
});
4213+
converter.addConversion([&](mlir::cir::FP128Type type) -> mlir::Type {
4214+
return mlir::FloatType::getF128(type.getContext());
4215+
});
42134216
converter.addConversion([&](mlir::cir::LongDoubleType type) -> mlir::Type {
42144217
return converter.convertType(type.getUnderlying());
42154218
});
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir --check-prefix=CIR %s
3+
// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -emit-llvm %s -o %t.ll
4+
// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
5+
6+
long double i = 0;
7+
long double t2(long double i2) {
8+
return i2 + i ;
9+
}
10+
11+
// CIR: cir.global external @i = #cir.fp<0.000000e+00> : !cir.long_double<!cir.f128> {alignment = 16 : i64} loc({{.*}})
12+
// CIR-LABEL: cir.func @t2(%arg0: !cir.long_double<!cir.f128> loc({{.*}})) -> !cir.long_double<!cir.f128>
13+
// CIR-NEXT: %[[#I2:]] = cir.alloca !cir.long_double<!cir.f128>, !cir.ptr<!cir.long_double<!cir.f128>>, ["i2", init] {alignment = 16 : i64}
14+
// CIR-NEXT: %[[#RETVAL:]] = cir.alloca !cir.long_double<!cir.f128>, !cir.ptr<!cir.long_double<!cir.f128>>, ["__retval"] {alignment = 16 : i64}
15+
// CIR-NEXT: cir.store %arg0, %[[#I2]] : !cir.long_double<!cir.f128>, !cir.ptr<!cir.long_double<!cir.f128>>
16+
// CIR-NEXT: %[[#I2_LOAD:]] = cir.load %[[#I2]] : !cir.ptr<!cir.long_double<!cir.f128>>, !cir.long_double<!cir.f128>
17+
// CIR-NEXT: %[[#I:]] = cir.get_global @i : !cir.ptr<!cir.long_double<!cir.f128>>
18+
// CIR-NEXT: %[[#I_LOAD:]] = cir.load %[[#I]] : !cir.ptr<!cir.long_double<!cir.f128>>, !cir.long_double<!cir.f128>
19+
// CIR-NEXT: %[[#ADD:]] = cir.binop(add, %[[#I2_LOAD]], %[[#I_LOAD]]) : !cir.long_double<!cir.f128>
20+
// CIR-NEXT: cir.store %[[#ADD]], %[[#RETVAL]] : !cir.long_double<!cir.f128>, !cir.ptr<!cir.long_double<!cir.f128>>
21+
// CIR-NEXT: %[[#RETVAL_LOAD:]] = cir.load %[[#RETVAL]] : !cir.ptr<!cir.long_double<!cir.f128>>, !cir.long_double<!cir.f128>
22+
// CIR-NEXT: cir.return %[[#RETVAL_LOAD]] : !cir.long_double<!cir.f128>
23+
24+
//LLVM: @i = global fp128 0xL00000000000000000000000000000000, align 16
25+
//LLVM-LABEL: define dso_local fp128 @t2(fp128 noundef %i2)
26+
//LLVM-NEXT : entry:
27+
//LLVM-NEXT : %[[#I2_ADDR:]]= alloca fp128, align 16
28+
//LLVM-NEXT : store fp128 %i2, ptr %[[#I2_ADDR]], align 16
29+
//LLVM-NEXT : %[[#I2_LOAD:]] = load fp128, ptr %[[#I2_ADDR]], align 16
30+
//LLVM-NEXT : %[[#I_LOAD:]] = load fp128, ptr @i, align 16
31+
//LLVM-NEXT : %[[#RETVAL:]] = fadd fp128 %[[#I2_LOAD]], %[[#I_LOAD]]
32+
//LLVM-NEXT : ret fp128 %[[#RETVAL]]

0 commit comments

Comments
 (0)