Skip to content

Commit

Permalink
[CIR][CIRGen] Support __builtin_isinf_sign
Browse files Browse the repository at this point in the history
  • Loading branch information
PikachuHyA committed Dec 3, 2024
1 parent eacaabb commit 650c796
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 0 deletions.
4 changes: 4 additions & 0 deletions clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,10 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
return createCast(cir::CastKind::int_to_ptr, src, newTy);
}

mlir::Value createIntToBoolCast(mlir::Value v) {
return createCast(cir::CastKind::int_to_bool, v, getBoolTy());
}

mlir::Value createGetMemberOp(mlir::Location &loc, mlir::Value structPtr,
const char *fldName, unsigned idx) {

Expand Down
21 changes: 21 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1424,6 +1424,27 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__builtin_matrix_column_major_store:
llvm_unreachable("BI__builtin_matrix_column_major_store NYI");

case Builtin::BI__builtin_isinf_sign: {
CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(*this, E);
mlir::Location Loc = getLoc(E->getBeginLoc());
mlir::Value Arg = emitScalarExpr(E->getArg(0));
mlir::Value AbsArg = builder.create<cir::FAbsOp>(Loc, Arg.getType(), Arg);
mlir::Value IsInf =
builder.createIsFPClass(Loc, AbsArg, FPClassTest::fcInf);
// FIMXE: CIR now will convert cir::BoolType to i8 type unconditionally.
// see https://github.com/llvm/clangir/issues/480
// fix the issue can eliminate redundant cast instruction
// for IsInf and IsNeg, i1 -> i8 -> i1
mlir::Value IsNeg = emitSignBit(Loc, *this, Arg);
auto IntTy = ConvertType(E->getType());
auto Zero = builder.getNullValue(IntTy, Loc);
auto One = builder.getConstant(Loc, cir::IntAttr::get(IntTy, 1));
auto NegativeOne = builder.getConstant(Loc, cir::IntAttr::get(IntTy, -1));
auto SignResult = builder.createSelect(Loc, IsNeg, NegativeOne, One);
auto Result = builder.createSelect(Loc, IsInf, SignResult, Zero);
return RValue::get(Result);
}

case Builtin::BI__builtin_flt_rounds:
llvm_unreachable("BI__builtin_flt_rounds NYI");

Expand Down
33 changes: 33 additions & 0 deletions clang/test/CIR/CodeGen/builtin-isinf-sign.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll
// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s

int test_float_isinf_sign(float x) {
// CIR-LABEL: test_float_isinf_sign
// CIR: %[[TMP0:.*]] = cir.load %{{.*}} : !cir.ptr<!cir.float>, !cir.float
// CIR: %[[TMP1:.*]] = cir.fabs %[[TMP0]] : !cir.float
// CIR: %[[IS_INF:.*]] = cir.is_fp_class %[[TMP1]], 516 : (!cir.float) -> !cir.bool
// CIR: %[[IS_NEG:.*]] = cir.signbit %[[TMP0]] : !cir.float -> !cir.bool
// CIR: %[[C_0:.*]] = cir.const #cir.int<0> : !s32i
// CIR: %[[C_1:.*]] = cir.const #cir.int<1> : !s32i
// CIR: %[[C_m1:.*]] = cir.const #cir.int<-1> : !s32i
// CIR: %[[TMP4:.*]] = cir.select if %[[IS_NEG]] then %[[C_m1]] else %[[C_1]] : (!cir.bool, !s32i, !s32i) -> !s32i
// CIR: %[[RET:.*]] = cir.select if %[[IS_INF]] then %[[TMP4]] else %[[C_0]] : (!cir.bool, !s32i, !s32i) -> !s32i
// CIR: cir.store %[[RET]], %{{.*}} : !s32i, !cir.ptr<!s32i>

// LLVM-LABEL: test_float_isinf_sign
// LLVM: %[[TMP0:.*]] = load float, ptr %{{.*}}
// LLVM: %[[TMP1:.*]] = call float @llvm.fabs.f32(float %[[TMP0]])
// LLVM: %[[IS_INF:.*]] = call i1 @llvm.is.fpclass.f32(float %[[TMP1]], i32 516)
// LLVM: %[[IS_INF_I8:.*]] = zext i1 %[[IS_INF]] to i8
// LLVM: %[[TMP1:.*]] = bitcast float %[[TMP0]] to i32
// LLVM: %[[IS_NEG:.*]] = icmp slt i32 %[[TMP1]], 0
// LLVM: %[[IS_NEG_I8:.*]] = zext i1 %[[IS_NEG]] to i8
// LLVM: %[[IS_NEG_I1:.*]] = trunc i8 %[[IS_NEG_I8]] to i1
// LLVM: %[[TMP2:.*]] = select i1 %[[IS_NEG_I1]], i32 -1, i32 1
// LLVM: %[[IS_INF_I1:.*]] = trunc i8 %[[IS_INF_I8]] to i1
// LLVM: %[[RET:.*]] = select i1 %[[IS_INF_I1]], i32 %[[TMP2]], i32 0
// LLVM: store i32 %[[RET]], ptr %{{.*}}, align 4
return __builtin_isinf_sign(x);
}

0 comments on commit 650c796

Please sign in to comment.