Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CIR][CIRGen][Builtin][Type] Support for IEEE Quad (long double) added (in CIR + Direct to LLVM) #966

Merged
merged 5 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion clang/include/clang/CIR/Dialect/IR/CIRTypes.td
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,13 @@ def CIR_FP80 : CIR_FloatType<"FP80", "f80"> {
}];
}

def CIR_FP128 : CIR_FloatType<"FP128", "f128"> {
let summary = "CIR type that represents IEEEquad 128-bit floating-point format";
let description = [{
Floating-point type that represents the IEEEquad 128-bit floating-point format.
}];
}

def CIR_LongDouble : CIR_FloatType<"LongDouble", "long_double"> {
let summary = "CIR extended-precision float type";
let description = [{
Expand All @@ -193,7 +200,7 @@ def CIR_LongDouble : CIR_FloatType<"LongDouble", "long_double"> {

// Constraints

def CIR_AnyFloat: AnyTypeOf<[CIR_Single, CIR_Double, CIR_FP80, CIR_LongDouble]>;
def CIR_AnyFloat: AnyTypeOf<[CIR_Single, CIR_Double, CIR_FP80, CIR_FP128, CIR_LongDouble]>;
def CIR_AnyIntOrFloat: AnyTypeOf<[CIR_AnyFloat, CIR_IntType]>;

//===----------------------------------------------------------------------===//
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CIR/CodeGen/CIRGenBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ class CIRGenBuilderTy : public CIRBaseBuilderTy {
if (&format == &llvm::APFloat::x87DoubleExtended())
return mlir::cir::LongDoubleType::get(getContext(), typeCache.FP80Ty);
if (&format == &llvm::APFloat::IEEEquad())
llvm_unreachable("NYI");
return mlir::cir::LongDoubleType::get(getContext(), typeCache.FP128Ty);
if (&format == &llvm::APFloat::PPCDoubleDouble())
llvm_unreachable("NYI");

Expand Down
7 changes: 4 additions & 3 deletions clang/lib/CIR/CodeGen/CIRGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "mlir/IR/Verifier.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/Cuda.h"
#include "clang/CIR/Dialect/IR/CIRTypes.h"
#include "clang/CIR/MissingFeatures.h"

#include "clang/AST/ASTConsumer.h"
Expand Down Expand Up @@ -74,8 +75,8 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/raw_ostream.h"

#include <iterator>
#include <numeric>
Expand Down Expand Up @@ -141,6 +142,7 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &context,
FloatTy = ::mlir::cir::SingleType::get(builder.getContext());
DoubleTy = ::mlir::cir::DoubleType::get(builder.getContext());
FP80Ty = ::mlir::cir::FP80Type::get(builder.getContext());
FP128Ty = ::mlir::cir::FP128Type::get(builder.getContext());

// TODO: PointerWidthInBits
PointerAlignInBytes =
Expand Down Expand Up @@ -192,8 +194,7 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &context,
theModule->setAttr("cir.sob",
mlir::cir::SignedOverflowBehaviorAttr::get(&context, sob));
auto lang = SourceLanguageAttr::get(&context, getCIRSourceLanguage());
theModule->setAttr(
"cir.lang", mlir::cir::LangAttr::get(&context, lang));
theModule->setAttr("cir.lang", mlir::cir::LangAttr::get(&context, lang));
theModule->setAttr("cir.triple", builder.getStringAttr(getTriple().str()));
// Set the module name to be the name of the main file. TranslationUnitDecl
// often contains invalid source locations and isn't a reliable source for the
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenTypeCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
#include "mlir/IR/Types.h"
#include "clang/AST/CharUnits.h"
#include "clang/Basic/AddressSpaces.h"
#include "clang/CIR/Dialect/IR/CIRTypes.h"
#include "clang/CIR/Dialect/IR/CIRAttrs.h"
#include "clang/CIR/Dialect/IR/CIRTypes.h"
#include "clang/CIR/MissingFeatures.h"

namespace cir {
Expand All @@ -41,6 +41,7 @@ struct CIRGenTypeCache {
mlir::cir::SingleType FloatTy;
mlir::cir::DoubleType DoubleTy;
mlir::cir::FP80Type FP80Ty;
mlir::cir::FP128Type FP128Ty;

/// int
mlir::Type UIntTy;
Expand Down
24 changes: 23 additions & 1 deletion clang/lib/CIR/Dialect/IR/CIRTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include <optional>
#include <stdexcept>

using cir::MissingFeatures;

Expand Down Expand Up @@ -761,6 +762,27 @@ FP80Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout,
return 16;
}

const llvm::fltSemantics &FP128Type::getFloatSemantics() const {
return llvm::APFloat::IEEEquad();
}

llvm::TypeSize
FP128Type::getTypeSizeInBits(const mlir::DataLayout &dataLayout,
mlir::DataLayoutEntryListRef params) const {
return llvm::TypeSize::getFixed(16);
}

uint64_t FP128Type::getABIAlignment(const mlir::DataLayout &dataLayout,
mlir::DataLayoutEntryListRef params) const {
return 16;
}

uint64_t
FP128Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout,
::mlir::DataLayoutEntryListRef params) const {
return 16;
}

const llvm::fltSemantics &LongDoubleType::getFloatSemantics() const {
return mlir::cast<mlir::cir::CIRFPTypeInterface>(getUnderlying())
.getFloatSemantics();
Expand Down Expand Up @@ -790,7 +812,7 @@ uint64_t LongDoubleType::getPreferredAlignment(
LogicalResult
LongDoubleType::verify(function_ref<InFlightDiagnostic()> emitError,
mlir::Type underlying) {
if (!mlir::isa<DoubleType, FP80Type>(underlying)) {
if (!mlir::isa<DoubleType, FP80Type, FP128Type>(underlying)) {
emitError() << "invalid underlying type for long double";
return failure();
}
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4164,6 +4164,9 @@ void prepareTypeConverter(mlir::LLVMTypeConverter &converter,
converter.addConversion([&](mlir::cir::FP80Type type) -> mlir::Type {
return mlir::FloatType::getF80(type.getContext());
});
converter.addConversion([&](mlir::cir::FP128Type type) -> mlir::Type {
return mlir::FloatType::getF128(type.getContext());
});
converter.addConversion([&](mlir::cir::LongDoubleType type) -> mlir::Type {
return converter.convertType(type.getUnderlying());
});
Expand Down
20 changes: 20 additions & 0 deletions clang/test/CIR/CodeGen/types-IEEE-quad.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir --check-prefix=CHECK %s

long double i = 0;
long double t2(long double i2) {
return i2 + i ;
}

// CHECK: cir.global external @i = #cir.fp<0.000000e+00> : !cir.long_double<!cir.f128> {alignment = 16 : i64} loc({{.*}})
// CHECK: cir.func @t2(%arg0: !cir.long_double<!cir.f128> loc({{.*}})) -> !cir.long_double<!cir.f128>
// CHECK: %{{[0-9]+}} = cir.alloca !cir.long_double<!cir.f128>, !cir.ptr<!cir.long_double<!cir.f128>>, ["i2", init] {alignment = 16 : i64}
// CHECK: %{{[0-9]+}} = cir.alloca !cir.long_double<!cir.f128>, !cir.ptr<!cir.long_double<!cir.f128>>, ["__retval"] {alignment = 16 : i64}
// CHECK: cir.store %arg0, %{{[0-9]+}} : !cir.long_double<!cir.f128>, !cir.ptr<!cir.long_double<!cir.f128>>
// CHECK: %{{[0-9]+}} = cir.load %{{[0-9]+}} : !cir.ptr<!cir.long_double<!cir.f128>>, !cir.long_double<!cir.f128>
// CHECK: %{{[0-9]+}} = cir.get_global @i : !cir.ptr<!cir.long_double<!cir.f128>>
// CHECK: %{{[0-9]+}} = cir.load %{{[0-9]+}} : !cir.ptr<!cir.long_double<!cir.f128>>, !cir.long_double<!cir.f128>
// CHECK: cir.store %{{[0-9]+}}, %{{[0-9]+}} : !cir.long_double<!cir.f128>, !cir.ptr<!cir.long_double<!cir.f128>>
// CHECK: %{{[0-9]+}} = cir.load %{{[0-9]+}} : !cir.ptr<!cir.long_double<!cir.f128>>, !cir.long_double<!cir.f128>
// CHECK: cir.return %{{[0-9]+}} : !cir.long_double<!cir.f128>

33 changes: 33 additions & 0 deletions clang/test/CIR/Lowering/types-IEEE-quad.cir
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// RUN: cir-opt %s -cir-to-llvm -o %t.mlir
// RUN: FileCheck --input-file=%t.mlir %s

module {
cir.global external dsolocal @i = #cir.fp<0.000000e+00> : !cir.long_double<!cir.f128> {alignment = 16 : i64}
cir.func @t2(%arg0: !cir.long_double<!cir.f128>) -> !cir.long_double<!cir.f128> {
%0 = cir.alloca !cir.long_double<!cir.f128>, !cir.ptr<!cir.long_double<!cir.f128>>, ["i2", init] {alignment = 16 : i64}
%1 = cir.alloca !cir.long_double<!cir.f128>, !cir.ptr<!cir.long_double<!cir.f128>>, ["__retval"] {alignment = 16 : i64}
cir.store %arg0, %0 : !cir.long_double<!cir.f128>, !cir.ptr<!cir.long_double<!cir.f128>>
%2 = cir.load %0 : !cir.ptr<!cir.long_double<!cir.f128>>, !cir.long_double<!cir.f128>
%3 = cir.get_global @i : !cir.ptr<!cir.long_double<!cir.f128>>
%4 = cir.load %3 : !cir.ptr<!cir.long_double<!cir.f128>>, !cir.long_double<!cir.f128>
%5 = cir.binop(add, %2, %4) : !cir.long_double<!cir.f128>
cir.store %5, %1 : !cir.long_double<!cir.f128>, !cir.ptr<!cir.long_double<!cir.f128>>
%6 = cir.load %1 : !cir.ptr<!cir.long_double<!cir.f128>>, !cir.long_double<!cir.f128>
cir.return %6 : !cir.long_double<!cir.f128>
}
}


// CHECK: llvm.mlir.global external @i(0.000000e+00 : f128) {addr_space = 0 : i32, alignment = 16 : i64} : f128
// CHECK: llvm.func @t2(%arg0: f128) -> f128 attributes {cir.extra_attrs = #fn_attr, global_visibility = #cir<visibility default>}
// CHECK: %{{[0-9]+}} = llvm.alloca %{{[0-9]+}} x f128 {alignment = 16 : i64} : (i64) -> !llvm.ptr
// CHECK: %{{[0-9]+}} = llvm.alloca %{{[0-9]+}} x f128 {alignment = 16 : i64} : (i64) -> !llvm.ptr
// CHECK: llvm.store %arg0, %{{[0-9]+}} {alignment = 16 : i64} : f128, !llvm.ptr
// CHECK: %{{[0-9]+}} = llvm.load %{{[0-9]+}} {alignment = 16 : i64} : !llvm.ptr -> f128
// CHECK: %{{[0-9]+}} = llvm.mlir.addressof @i : !llvm.ptr
// CHECK: %{{[0-9]+}} = llvm.load %{{[0-9]+}} {alignment = 16 : i64} : !llvm.ptr -> f128
// CHECK: %{{[0-9]+}} = llvm.fadd %{{[0-9]+}}, %{{[0-9]+}} : f128
// CHECK: llvm.store %{{[0-9]+}}, %{{[0-9]+}} {alignment = 16 : i64} : f128, !llvm.ptr
// CHECK: %{{[0-9]+}} = llvm.load %{{[0-9]+}} {alignment = 16 : i64} : !llvm.ptr -> f128
// CHECK: llvm.return %{{[0-9]+}} : f128