Skip to content

Commit 5364b31

Browse files
authored
[CIR] Implement fabs operation. (#254)
Following discussion in #237 this adds support for `fabs` builtins which are used extensively in llvm-test-suite.
1 parent f848d9b commit 5364b31

File tree

6 files changed

+74
-3
lines changed

6 files changed

+74
-3
lines changed

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2035,6 +2035,31 @@ def MemCpyOp : CIR_Op<"libc.memcpy"> {
20352035
}];
20362036
}
20372037

2038+
//===----------------------------------------------------------------------===//
2039+
// FAbsOp
2040+
//===----------------------------------------------------------------------===//
2041+
2042+
def FAbsOp : CIR_Op<"fabs", [Pure, SameOperandsAndResultType]> {
2043+
let arguments = (ins AnyFloat:$src);
2044+
let results = (outs AnyFloat:$result);
2045+
let summary = "Returns absolute value for floating-point input.";
2046+
let description = [{
2047+
Equivalent to libc's `fabs` and LLVM's intrinsic with the same name.
2048+
2049+
Examples:
2050+
2051+
```mlir
2052+
%1 = cir.const(1.0 : f64) : f64
2053+
%2 = cir.fabs %1 : f64
2054+
```
2055+
}];
2056+
2057+
let assemblyFormat = [{
2058+
$src `:` type($src) attr-dict
2059+
}];
2060+
let hasVerifier = 0;
2061+
}
2062+
20382063
//===----------------------------------------------------------------------===//
20392064
// Variadic Operations
20402065
//===----------------------------------------------------------------------===//

clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,13 @@ RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
142142
case Builtin::BI__builtin_fabsf:
143143
case Builtin::BI__builtin_fabsf16:
144144
case Builtin::BI__builtin_fabsl:
145-
case Builtin::BI__builtin_fabsf128:
146-
llvm_unreachable("NYI");
145+
case Builtin::BI__builtin_fabsf128: {
146+
mlir::Value Src0 = buildScalarExpr(E->getArg(0));
147+
auto SrcType = Src0.getType();
148+
auto Call =
149+
builder.create<mlir::cir::FAbsOp>(Src0.getLoc(), SrcType, Src0);
150+
return RValue::get(Call->getResult(0));
151+
}
147152

148153
case Builtin::BIfloor:
149154
case Builtin::BIfloorf:

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1821,6 +1821,19 @@ class CIRPtrDiffOpLowering
18211821
}
18221822
};
18231823

1824+
class CIRFAbsOpLowering : public mlir::OpConversionPattern<mlir::cir::FAbsOp> {
1825+
public:
1826+
using OpConversionPattern<mlir::cir::FAbsOp>::OpConversionPattern;
1827+
1828+
mlir::LogicalResult
1829+
matchAndRewrite(mlir::cir::FAbsOp op, OpAdaptor adaptor,
1830+
mlir::ConversionPatternRewriter &rewriter) const override {
1831+
rewriter.replaceOpWithNewOp<mlir::LLVM::FAbsOp>(
1832+
op, adaptor.getOperands().front());
1833+
return mlir::success();
1834+
}
1835+
};
1836+
18241837
void populateCIRToLLVMConversionPatterns(mlir::RewritePatternSet &patterns,
18251838
mlir::TypeConverter &converter) {
18261839
patterns.add<CIRReturnLowering>(patterns.getContext());
@@ -1833,7 +1846,8 @@ void populateCIRToLLVMConversionPatterns(mlir::RewritePatternSet &patterns,
18331846
CIRVAStartLowering, CIRVAEndLowering, CIRVACopyLowering,
18341847
CIRVAArgLowering, CIRBrOpLowering, CIRTernaryOpLowering,
18351848
CIRGetMemberOpLowering, CIRSwitchOpLowering,
1836-
CIRPtrDiffOpLowering, CIRCopyOpLowering, CIRMemCpyOpLowering>(
1849+
CIRPtrDiffOpLowering, CIRCopyOpLowering, CIRMemCpyOpLowering,
1850+
CIRFAbsOpLowering>(
18371851
converter, patterns.getContext());
18381852
}
18391853

clang/test/CIR/CodeGen/libc.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,15 @@ void testMemcpy(void *src, const void *dst, unsigned long size) {
77
memcpy(dst, src, size);
88
// CHECK: cir.libc.memcpy %{{.+}} bytes from %{{.+}} to %{{.+}} : !u64i, !cir.ptr<!void> -> !cir.ptr<!void>
99
}
10+
11+
double fabs(double);
12+
double testFabs(double x) {
13+
return fabs(x);
14+
// CHECK: cir.fabs %{{.+}} : f64
15+
}
16+
17+
float fabsf(float);
18+
float testFabsf(float x) {
19+
return fabsf(x);
20+
// CHECK: cir.fabs %{{.+}} : f32
21+
}

clang/test/CIR/IR/libc-fabs.cir

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: cir-opt %s
2+
3+
!u32i = !cir.int<u, 32>
4+
module {
5+
cir.func @foo(%arg0: f64) -> f64 {
6+
%0 = cir.fabs %arg0 : f64
7+
cir.return %0 : f64
8+
}
9+
}

clang/test/CIR/Lowering/libc.cir

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,10 @@ module {
99
// CHECK: "llvm.intr.memcpy"(%{{.+}}, %{{.+}}, %{{.+}}) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i64) -> ()
1010
cir.return
1111
}
12+
13+
cir.func @shouldLowerLibcFAbsBuiltin(%arg0: f64) -> f64 {
14+
%0 = cir.fabs %arg0 : f64
15+
// CHECK: %0 = llvm.intr.fabs(%arg0) : (f64) -> f64
16+
cir.return %0 : f64
17+
}
1218
}

0 commit comments

Comments
 (0)