Skip to content

Commit 28dad5f

Browse files
mvvsmklanza
authored andcommitted
[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 1407152 commit 28dad5f

File tree

7 files changed

+66
-7
lines changed

7 files changed

+66
-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: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,21 @@ uint64_t FP80Type::getABIAlignment(const mlir::DataLayout &dataLayout,
688688
return 16;
689689
}
690690

691+
const llvm::fltSemantics &FP128Type::getFloatSemantics() const {
692+
return llvm::APFloat::IEEEquad();
693+
}
694+
695+
llvm::TypeSize
696+
FP128Type::getTypeSizeInBits(const mlir::DataLayout &dataLayout,
697+
mlir::DataLayoutEntryListRef params) const {
698+
return llvm::TypeSize::getFixed(16);
699+
}
700+
701+
uint64_t FP128Type::getABIAlignment(const mlir::DataLayout &dataLayout,
702+
mlir::DataLayoutEntryListRef params) const {
703+
return 16;
704+
}
705+
691706
const llvm::fltSemantics &LongDoubleType::getFloatSemantics() const {
692707
return mlir::cast<mlir::cir::CIRFPTypeInterface>(getUnderlying())
693708
.getFloatSemantics();
@@ -710,7 +725,7 @@ LongDoubleType::getABIAlignment(const mlir::DataLayout &dataLayout,
710725
LogicalResult
711726
LongDoubleType::verify(function_ref<InFlightDiagnostic()> emitError,
712727
mlir::Type underlying) {
713-
if (!mlir::isa<DoubleType, FP80Type>(underlying)) {
728+
if (!mlir::isa<DoubleType, FP80Type, FP128Type>(underlying)) {
714729
emitError() << "invalid underlying type for long double";
715730
return failure();
716731
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4208,6 +4208,9 @@ void prepareTypeConverter(mlir::LLVMTypeConverter &converter,
42084208
converter.addConversion([&](mlir::cir::FP80Type type) -> mlir::Type {
42094209
return mlir::Float80Type::get(type.getContext());
42104210
});
4211+
converter.addConversion([&](mlir::cir::FP128Type type) -> mlir::Type {
4212+
return mlir::Float128Type::get(type.getContext());
4213+
});
42114214
converter.addConversion([&](mlir::cir::LongDoubleType type) -> mlir::Type {
42124215
return converter.convertType(type.getUnderlying());
42134216
});
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)