Skip to content

Commit

Permalink
[CIR] [CodeGen] Implement unary floating point builtins
Browse files Browse the repository at this point in the history
  • Loading branch information
philnik777 committed Jan 6, 2024
1 parent 3adad6b commit b9668c2
Show file tree
Hide file tree
Showing 3 changed files with 657 additions and 56 deletions.
74 changes: 39 additions & 35 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -1447,13 +1447,13 @@ def VTableAddrPointOp : CIR_Op<"vtable.address_point",

def SetBitfieldOp : CIR_Op<"set_bitfield"> {
let summary = "Set a bitfield";
let description = [{
The `cir.set_bitfield` operation provides a store-like access to
let description = [{
The `cir.set_bitfield` operation provides a store-like access to
a bit field of a record.

It expects an address of a storage where to store, a type of the storage,
a value being stored, a name of a bit field, a pointer to the storage in the
base record, a size of the storage, a size the bit field, an offset
base record, a size of the storage, a size the bit field, an offset
of the bit field and a sign. Returns a value being stored.

Example.
Expand Down Expand Up @@ -1496,20 +1496,20 @@ def SetBitfieldOp : CIR_Op<"set_bitfield"> {

let assemblyFormat = [{ `(`$bitfield_info`,` $dst`:`type($dst)`,`
$src`:`type($src) `)` attr-dict `->` type($result) }];

let builders = [
OpBuilder<(ins "Type":$type,
"Value":$dst,
"Type":$storage_type,
"Value":$src,
"StringRef":$name,
"unsigned":$size,
"unsigned":$size,
"unsigned":$offset,
"bool":$is_signed
),
[{
BitfieldInfoAttr info =
BitfieldInfoAttr::get($_builder.getContext(),
[{
BitfieldInfoAttr info =
BitfieldInfoAttr::get($_builder.getContext(),
name, storage_type,
size, offset, is_signed);
build($_builder, $_state, type, dst, src, info);
Expand All @@ -1523,7 +1523,7 @@ def SetBitfieldOp : CIR_Op<"set_bitfield"> {

def GetBitfieldOp : CIR_Op<"get_bitfield"> {
let summary = "Get a bitfield";
let description = [{
let description = [{
The `cir.get_bitfield` operation provides a load-like access to
a bit field of a record.

Expand Down Expand Up @@ -1561,13 +1561,13 @@ def GetBitfieldOp : CIR_Op<"get_bitfield"> {
}];

let arguments = (ins
AnyType:$addr,
AnyType:$addr,
BitfieldInfoAttr:$bitfield_info
);

let results = (outs CIR_IntType:$result);

let assemblyFormat = [{ `(`$bitfield_info `,` $addr attr-dict `:`
let assemblyFormat = [{ `(`$bitfield_info `,` $addr attr-dict `:`
type($addr) `)` `->` type($result) }];

let builders = [
Expand All @@ -1580,8 +1580,8 @@ def GetBitfieldOp : CIR_Op<"get_bitfield"> {
"bool":$is_signed
),
[{
BitfieldInfoAttr info =
BitfieldInfoAttr::get($_builder.getContext(),
BitfieldInfoAttr info =
BitfieldInfoAttr::get($_builder.getContext(),
name, storage_type,
size, offset, is_signed);
build($_builder, $_state, type, addr, info);
Expand Down Expand Up @@ -2367,29 +2367,33 @@ def IterEndOp : CIR_Op<"iterator_end"> {
}

//===----------------------------------------------------------------------===//
// FAbsOp
// Floating Point Ops
//===----------------------------------------------------------------------===//

def FAbsOp : CIR_Op<"fabs", [Pure, SameOperandsAndResultType]> {
class UnaryFPToFPBuiltinOp<string mnemonic>
: CIR_Op<mnemonic, [Pure, SameOperandsAndResultType]> {
let arguments = (ins AnyFloat:$src);
let results = (outs AnyFloat:$result);
let summary = "Returns absolute value for floating-point input.";
let description = [{
Equivalent to libc's `fabs` and LLVM's intrinsic with the same name.

Examples:

```mlir
%1 = cir.const(1.0 : f64) : f64
%2 = cir.fabs %1 : f64
```
}];

let assemblyFormat = [{
$src `:` type($src) attr-dict
}];
let hasVerifier = 0;
}
let summary = "libc builtin equivalent ignoring "
"floating point exceptions and errno";
let assemblyFormat = "$src `:` type($src) attr-dict";
}

def CeilOp : UnaryFPToFPBuiltinOp<"ceil">;
def CosOp : UnaryFPToFPBuiltinOp<"cos">;
def ExpOp : UnaryFPToFPBuiltinOp<"exp">;
def Exp2Op : UnaryFPToFPBuiltinOp<"exp2">;
def FloorOp : UnaryFPToFPBuiltinOp<"floor">;
def FAbsOp : UnaryFPToFPBuiltinOp<"fabs">;
def LogOp : UnaryFPToFPBuiltinOp<"log">;
def Log10Op : UnaryFPToFPBuiltinOp<"log10">;
def Log2Op : UnaryFPToFPBuiltinOp<"log2">;
def NearbyintOp : UnaryFPToFPBuiltinOp<"nearbyint">;
def RintOp : UnaryFPToFPBuiltinOp<"rint">;
def RoundOp : UnaryFPToFPBuiltinOp<"round">;
def SinOp : UnaryFPToFPBuiltinOp<"sin">;
def SqrtOp : UnaryFPToFPBuiltinOp<"sqrt">;
def TruncOp : UnaryFPToFPBuiltinOp<"trunc">;

//===----------------------------------------------------------------------===//
// Variadic Operations
Expand Down Expand Up @@ -2593,19 +2597,19 @@ def CIR_InlineAsmOp : CIR_Op<"asm", [RecursiveMemoryEffects]> {

```
```mlir
cir.asm(x86_att, {"xyz"}) -> !void
cir.asm(x86_att, {"xyz"}) -> !void
```
}];

let results = (outs Optional<AnyType>:$res);

let arguments = (
ins StrAttr:$asm_string,
AsmFlavor:$asm_flavor);
AsmFlavor:$asm_flavor);

let assemblyFormat = [{
`(`$asm_flavor`,` `{` $asm_string `}` `)` attr-dict `:` type($res)
}];
}];
}

#endif // MLIR_CIR_DIALECT_CIR_OPS
50 changes: 29 additions & 21 deletions clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,19 @@ static RValue buildLibraryCall(CIRGenFunction &CGF, const FunctionDecl *FD,
return CGF.buildCall(E->getCallee()->getType(), callee, E, ReturnValueSlot());
}

template <class Operation>
static RValue buildUnaryFPBuiltin(CIRGenFunction &CGF, const CallExpr &E) {
auto Arg = CGF.buildScalarExpr(E.getArg(0));

CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(CGF, &E);
if (CGF.getBuilder().getIsFPConstrained())
llvm_unreachable("constraint FP operations are NYI");

auto Call =
CGF.getBuilder().create<Operation>(Arg.getLoc(), Arg.getType(), Arg);
return RValue::get(Call->getResult(0));
}

RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
const CallExpr *E,
ReturnValueSlot ReturnValue) {
Expand Down Expand Up @@ -93,7 +106,7 @@ RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__builtin_ceilf16:
case Builtin::BI__builtin_ceill:
case Builtin::BI__builtin_ceilf128:
llvm_unreachable("NYI");
return buildUnaryFPBuiltin<mlir::cir::CeilOp>(*this, *E);

case Builtin::BIcopysign:
case Builtin::BIcopysignf:
Expand All @@ -113,7 +126,7 @@ RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__builtin_cosf16:
case Builtin::BI__builtin_cosl:
case Builtin::BI__builtin_cosf128:
llvm_unreachable("NYI");
return buildUnaryFPBuiltin<mlir::cir::CosOp>(*this, *E);

case Builtin::BIexp:
case Builtin::BIexpf:
Expand All @@ -123,7 +136,7 @@ RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__builtin_expf16:
case Builtin::BI__builtin_expl:
case Builtin::BI__builtin_expf128:
llvm_unreachable("NYI");
return buildUnaryFPBuiltin<mlir::cir::ExpOp>(*this, *E);

case Builtin::BIexp2:
case Builtin::BIexp2f:
Expand All @@ -133,7 +146,7 @@ RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__builtin_exp2f16:
case Builtin::BI__builtin_exp2l:
case Builtin::BI__builtin_exp2f128:
llvm_unreachable("NYI");
return buildUnaryFPBuiltin<mlir::cir::Exp2Op>(*this, *E);

case Builtin::BIfabs:
case Builtin::BIfabsf:
Expand All @@ -142,13 +155,8 @@ RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__builtin_fabsf:
case Builtin::BI__builtin_fabsf16:
case Builtin::BI__builtin_fabsl:
case Builtin::BI__builtin_fabsf128: {
mlir::Value Src0 = buildScalarExpr(E->getArg(0));
auto SrcType = Src0.getType();
auto Call =
builder.create<mlir::cir::FAbsOp>(Src0.getLoc(), SrcType, Src0);
return RValue::get(Call->getResult(0));
}
case Builtin::BI__builtin_fabsf128:
return buildUnaryFPBuiltin<mlir::cir::FAbsOp>(*this, *E);

case Builtin::BIfloor:
case Builtin::BIfloorf:
Expand All @@ -158,7 +166,7 @@ RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__builtin_floorf16:
case Builtin::BI__builtin_floorl:
case Builtin::BI__builtin_floorf128:
llvm_unreachable("NYI");
return buildUnaryFPBuiltin<mlir::cir::FloorOp>(*this, *E);

case Builtin::BIfma:
case Builtin::BIfmaf:
Expand Down Expand Up @@ -211,7 +219,7 @@ RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__builtin_logf16:
case Builtin::BI__builtin_logl:
case Builtin::BI__builtin_logf128:
llvm_unreachable("NYI");
return buildUnaryFPBuiltin<mlir::cir::LogOp>(*this, *E);

case Builtin::BIlog10:
case Builtin::BIlog10f:
Expand All @@ -221,7 +229,7 @@ RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__builtin_log10f16:
case Builtin::BI__builtin_log10l:
case Builtin::BI__builtin_log10f128:
llvm_unreachable("NYI");
return buildUnaryFPBuiltin<mlir::cir::Log10Op>(*this, *E);

case Builtin::BIlog2:
case Builtin::BIlog2f:
Expand All @@ -231,7 +239,7 @@ RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__builtin_log2f16:
case Builtin::BI__builtin_log2l:
case Builtin::BI__builtin_log2f128:
llvm_unreachable("NYI");
return buildUnaryFPBuiltin<mlir::cir::Log2Op>(*this, *E);

case Builtin::BInearbyint:
case Builtin::BInearbyintf:
Expand All @@ -240,7 +248,7 @@ RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__builtin_nearbyintf:
case Builtin::BI__builtin_nearbyintl:
case Builtin::BI__builtin_nearbyintf128:
llvm_unreachable("NYI");
return buildUnaryFPBuiltin<mlir::cir::NearbyintOp>(*this, *E);

case Builtin::BIpow:
case Builtin::BIpowf:
Expand All @@ -260,7 +268,7 @@ RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__builtin_rintf16:
case Builtin::BI__builtin_rintl:
case Builtin::BI__builtin_rintf128:
llvm_unreachable("NYI");
return buildUnaryFPBuiltin<mlir::cir::RintOp>(*this, *E);

case Builtin::BIround:
case Builtin::BIroundf:
Expand All @@ -270,7 +278,7 @@ RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__builtin_roundf16:
case Builtin::BI__builtin_roundl:
case Builtin::BI__builtin_roundf128:
llvm_unreachable("NYI");
return buildUnaryFPBuiltin<mlir::cir::RoundOp>(*this, *E);

case Builtin::BIsin:
case Builtin::BIsinf:
Expand All @@ -280,7 +288,7 @@ RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__builtin_sinf16:
case Builtin::BI__builtin_sinl:
case Builtin::BI__builtin_sinf128:
llvm_unreachable("NYI");
return buildUnaryFPBuiltin<mlir::cir::SinOp>(*this, *E);

case Builtin::BIsqrt:
case Builtin::BIsqrtf:
Expand All @@ -290,7 +298,7 @@ RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__builtin_sqrtf16:
case Builtin::BI__builtin_sqrtl:
case Builtin::BI__builtin_sqrtf128:
llvm_unreachable("NYI");
return buildUnaryFPBuiltin<mlir::cir::SqrtOp>(*this, *E);

case Builtin::BItrunc:
case Builtin::BItruncf:
Expand All @@ -300,7 +308,7 @@ RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__builtin_truncf16:
case Builtin::BI__builtin_truncl:
case Builtin::BI__builtin_truncf128:
llvm_unreachable("NYI");
return buildUnaryFPBuiltin<mlir::cir::TruncOp>(*this, *E);

case Builtin::BIlround:
case Builtin::BIlroundf:
Expand Down
Loading

0 comments on commit b9668c2

Please sign in to comment.