Skip to content

Commit

Permalink
[CIR][CIRGen] handle __builtin_elementwise_acos (#1362)
Browse files Browse the repository at this point in the history
Traditional Clang implementation:
https://github.com/llvm/clangir/blob/a0091e38f1027e35d17819e02ee1ae257a12d296/clang/lib/CodeGen/CGBuiltin.cpp#L4116-L4118

I use the first argument type as the return type. It is OK for
`__builtin_elementwise_acos`, however, I'm not sure it is OK for other
builtin functions.

Resolves: #1361
  • Loading branch information
FantasqueX authored Feb 19, 2025
1 parent a99b65f commit dbe544d
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 2 deletions.
5 changes: 3 additions & 2 deletions clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1356,8 +1356,9 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
mlir::Value result = call->getResult(0);
return RValue::get(result);
}
case Builtin::BI__builtin_elementwise_acos:
llvm_unreachable("BI__builtin_elementwise_acos NYI");
case Builtin::BI__builtin_elementwise_acos: {
return emitBuiltinWithOneOverloadedType<1>(E, "acos");
}
case Builtin::BI__builtin_elementwise_asin:
llvm_unreachable("BI__builtin_elementwise_asin NYI");
case Builtin::BI__builtin_elementwise_atan:
Expand Down
13 changes: 13 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -1403,6 +1403,19 @@ class CIRGenFunction : public CIRGenTypeCache {
RValue emitBuiltinExpr(const clang::GlobalDecl GD, unsigned BuiltinID,
const clang::CallExpr *E, ReturnValueSlot ReturnValue);
RValue emitRotate(const CallExpr *E, bool IsRotateRight);
template <uint32_t N>
RValue emitBuiltinWithOneOverloadedType(const CallExpr *E,
llvm::StringRef Name) {
static_assert(N, "expect non-empty argument");
mlir::Type cirTy = convertType(E->getArg(0)->getType());
SmallVector<mlir::Value, N> args;
for (uint32_t i = 0; i < N; ++i) {
args.push_back(emitScalarExpr(E->getArg(i)));
}
const auto call = builder.create<cir::LLVMIntrinsicCallOp>(
getLoc(E->getExprLoc()), builder.getStringAttr(Name), cirTy, args);
return RValue::get(call->getResult(0));
}
mlir::Value emitTargetBuiltinExpr(unsigned BuiltinID,
const clang::CallExpr *E,
ReturnValueSlot ReturnValue);
Expand Down
21 changes: 21 additions & 0 deletions clang/test/CIR/CodeGen/builtins-elementwise.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,24 @@ void test_builtin_elementwise_abs(vint4 vi4, int i, float f, double d,
// LLVM: {{%.*}} = call <4 x double> @llvm.fabs.v4f64(<4 x double> {{%.*}})
vd4 = __builtin_elementwise_abs(vd4);
}

void test_builtin_elementwise_acos(float f, double d, vfloat4 vf4,
vdouble4 vd4) {
// CIR-LABEL: test_builtin_elementwise_acos
// LLVM-LABEL: test_builtin_elementwise_acos
// CIR: {{%.*}} = cir.llvm.intrinsic "acos" {{%.*}} : (!cir.float) -> !cir.float
// LLVM: {{%.*}} = call float @llvm.acos.f32(float {{%.*}})
f = __builtin_elementwise_acos(f);

// CIR: {{%.*}} = cir.llvm.intrinsic "acos" {{%.*}} : (!cir.double) -> !cir.double
// LLVM: {{%.*}} = call double @llvm.acos.f64(double {{%.*}})
d = __builtin_elementwise_acos(d);

// CIR: {{%.*}} = cir.llvm.intrinsic "acos" {{%.*}} : (!cir.vector<!cir.float x 4>) -> !cir.vector<!cir.float x 4>
// LLVM: {{%.*}} = call <4 x float> @llvm.acos.v4f32(<4 x float> {{%.*}})
vf4 = __builtin_elementwise_acos(vf4);

// CIR: {{%.*}} = cir.llvm.intrinsic "acos" {{%.*}} : (!cir.vector<!cir.double x 4>) -> !cir.vector<!cir.double x 4>
// LLVM: {{%.*}} = call <4 x double> @llvm.acos.v4f64(<4 x double> {{%.*}})
vd4 = __builtin_elementwise_acos(vd4);
}

0 comments on commit dbe544d

Please sign in to comment.