Skip to content

Commit dc84f3a

Browse files
authored
[CIR] Upstream builtin FAbs op (#151750)
Upstreaming FAbsOp as a prerequisite for upstreaming ComplexDivOp
1 parent 57fb38a commit dc84f3a

File tree

5 files changed

+80
-1
lines changed

5 files changed

+80
-1
lines changed

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3310,4 +3310,28 @@ def CIR_ExpectOp : CIR_Op<"expect", [
33103310
}];
33113311
}
33123312

3313+
//===----------------------------------------------------------------------===//
3314+
// Floating Point Ops
3315+
//===----------------------------------------------------------------------===//
3316+
3317+
class CIR_UnaryFPToFPBuiltinOp<string mnemonic, string llvmOpName>
3318+
: CIR_Op<mnemonic, [Pure, SameOperandsAndResultType]>
3319+
{
3320+
let arguments = (ins CIR_AnyFloatOrVecOfFloatType:$src);
3321+
let results = (outs CIR_AnyFloatOrVecOfFloatType:$result);
3322+
3323+
let assemblyFormat = "$src `:` type($src) attr-dict";
3324+
3325+
let llvmOp = llvmOpName;
3326+
}
3327+
3328+
def CIR_FAbsOp : CIR_UnaryFPToFPBuiltinOp<"fabs", "FAbsOp"> {
3329+
let summary = "Computes the floating-point absolute value";
3330+
let description = [{
3331+
`cir.fabs` computes the absolute value of a floating-point operand
3332+
and returns a result of the same type, ignoring floating-point
3333+
exceptions. It does not set `errno`.
3334+
}];
3335+
}
3336+
33133337
#endif // CLANG_CIR_DIALECT_IR_CIROPS_TD

clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,19 @@ RValue CIRGenFunction::emitRotate(const CallExpr *e, bool isRotateLeft) {
7272
return RValue::get(r);
7373
}
7474

75+
template <class Operation>
76+
static RValue emitUnaryMaybeConstrainedFPBuiltin(CIRGenFunction &cgf,
77+
const CallExpr &e) {
78+
mlir::Value arg = cgf.emitScalarExpr(e.getArg(0));
79+
80+
assert(!cir::MissingFeatures::cgFPOptionsRAII());
81+
assert(!cir::MissingFeatures::fpConstraints());
82+
83+
auto call =
84+
Operation::create(cgf.getBuilder(), arg.getLoc(), arg.getType(), arg);
85+
return RValue::get(call->getResult(0));
86+
}
87+
7588
RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
7689
const CallExpr *e,
7790
ReturnValueSlot returnValue) {
@@ -112,6 +125,16 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
112125
default:
113126
break;
114127

128+
case Builtin::BIfabs:
129+
case Builtin::BIfabsf:
130+
case Builtin::BIfabsl:
131+
case Builtin::BI__builtin_fabs:
132+
case Builtin::BI__builtin_fabsf:
133+
case Builtin::BI__builtin_fabsf16:
134+
case Builtin::BI__builtin_fabsl:
135+
case Builtin::BI__builtin_fabsf128:
136+
return emitUnaryMaybeConstrainedFPBuiltin<cir::FAbsOp>(*this, *e);
137+
115138
case Builtin::BI__assume:
116139
case Builtin::BI__builtin_assume: {
117140
if (e->getArg(0)->HasSideEffects(getContext()))

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,15 @@ mlir::LogicalResult CIRToLLVMExpectOpLowering::matchAndRewrite(
12961296
return mlir::success();
12971297
}
12981298

1299+
mlir::LogicalResult CIRToLLVMFAbsOpLowering::matchAndRewrite(
1300+
cir::FAbsOp op, OpAdaptor adaptor,
1301+
mlir::ConversionPatternRewriter &rewriter) const {
1302+
mlir::Type resTy = typeConverter->convertType(op.getType());
1303+
rewriter.replaceOpWithNewOp<mlir::LLVM::FAbsOp>(op, resTy,
1304+
adaptor.getOperands()[0]);
1305+
return mlir::success();
1306+
}
1307+
12991308
/// Convert the `cir.func` attributes to `llvm.func` attributes.
13001309
/// Only retain those attributes that are not constructed by
13011310
/// `LLVMFuncOp::build`. If `filterArgAttrs` is set, also filter out
@@ -2291,6 +2300,7 @@ void ConvertCIRToLLVMPass::runOnOperation() {
22912300
CIRToLLVMComplexSubOpLowering,
22922301
CIRToLLVMConstantOpLowering,
22932302
CIRToLLVMExpectOpLowering,
2303+
CIRToLLVMFAbsOpLowering,
22942304
CIRToLLVMFuncOpLowering,
22952305
CIRToLLVMGetBitfieldOpLowering,
22962306
CIRToLLVMGetGlobalOpLowering,
@@ -2313,7 +2323,6 @@ void ConvertCIRToLLVMPass::runOnOperation() {
23132323
CIRToLLVMVecSplatOpLowering,
23142324
CIRToLLVMVecTernaryOpLowering,
23152325
CIRToLLVMUnreachableOpLowering
2316-
// clang-format on
23172326
>(converter, patterns.getContext());
23182327

23192328
processCIRAttrs(module);

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,15 @@ class CIRToLLVMGetBitfieldOpLowering
648648
mlir::ConversionPatternRewriter &) const override;
649649
};
650650

651+
class CIRToLLVMFAbsOpLowering : public mlir::OpConversionPattern<cir::FAbsOp> {
652+
public:
653+
using mlir::OpConversionPattern<cir::FAbsOp>::OpConversionPattern;
654+
655+
mlir::LogicalResult
656+
matchAndRewrite(cir::FAbsOp op, OpAdaptor,
657+
mlir::ConversionPatternRewriter &) const override;
658+
};
659+
651660
} // namespace direct
652661
} // namespace cir
653662

clang/test/CIR/CodeGen/builtins.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
3+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll
4+
// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
5+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll
6+
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
7+
8+
double fabs(double x) {
9+
return __builtin_fabs(x);
10+
}
11+
12+
// CIR: {{.*}} = cir.fabs {{.*}} : !cir.double
13+
// LLVM: {{.*}} = call double @llvm.fabs.f64(double {{.*}})
14+
// OGCG: {{.*}} = call double @llvm.fabs.f64(double {{.*}})

0 commit comments

Comments
 (0)