Author: Ayokunle Amodu
Date: 2026-03-03T14:01:49-08:00
New Revision: 1953b87a31a9b7de9e34deaa7e94ee59b3e7de39

URL: 
https://github.com/llvm/llvm-project/commit/1953b87a31a9b7de9e34deaa7e94ee59b3e7de39
DIFF: 
https://github.com/llvm/llvm-project/commit/1953b87a31a9b7de9e34deaa7e94ee59b3e7de39.diff

LOG: [CIR][CodeGen] Upstream support for `__builtin_isinf_sign` (#183977)

This adds CIR codegen and lowering support for `__builtin_isinf_sign`.

Added: 
    clang/test/CIR/CodeGenBuiltins/builtin-isinf-sign.c

Modified: 
    clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
    clang/include/clang/CIR/Dialect/IR/CIROps.td
    clang/include/clang/CIR/MissingFeatures.h
    clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
    clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index 72de34ffad77b..f51bea894d2ae 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -547,6 +547,11 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
     return cir::VecInsertOp::create(*this, loc, vec, newElt, idxVal);
   }
 
+  cir::SignBitOp createSignBit(mlir::Location loc, mlir::Value val) {
+    auto resTy = cir::BoolType::get(getContext());
+    return cir::SignBitOp::create(*this, loc, resTy, val);
+  }
+
   
//===--------------------------------------------------------------------===//
   // Binary Operators
   
//===--------------------------------------------------------------------===//

diff  --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 3a17b0a381a76..7f73c606f1537 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -484,6 +484,23 @@ def CIR_ConstantOp : CIR_Op<"const", [
   let isLLVMLoweringRecursive = true;
 }
 
+//===----------------------------------------------------------------------===//
+// SignBitOp
+//===----------------------------------------------------------------------===//
+
+def SignBitOp : CIR_Op<"signbit", [Pure]> {
+  let summary = "Checks the sign of a floating-point number";
+  let description = [{
+    It returns whether the sign bit (i.e. the highest bit) of the input operand
+    is set.
+  }];
+  let arguments = (ins CIR_AnyFloatType:$input);
+  let results = (outs CIR_BoolType:$res);
+  let assemblyFormat = [{
+      $input attr-dict `:` type($input) `->` qualified(type($res))
+  }];
+}
+
 
//===----------------------------------------------------------------------===//
 // C/C++ memory order definitions
 
//===----------------------------------------------------------------------===//

diff  --git a/clang/include/clang/CIR/MissingFeatures.h 
b/clang/include/clang/CIR/MissingFeatures.h
index ab05d2191d9b0..d206503d914f5 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -272,6 +272,7 @@ struct MissingFeatures {
   static bool emitNullabilityCheck() { return false; }
   static bool emitTypeCheck() { return false; }
   static bool emitTypeMetadataCodeForVCall() { return false; }
+  static bool isPPC_FP128Ty() { return false; }
 
   // Fast math.
   static bool fastMathGuard() { return false; }

diff  --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index b11d8f4783db0..3b7ad5c4929fe 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -86,6 +86,13 @@ static mlir::Value emitFromInt(CIRGenFunction &cgf, 
mlir::Value v, QualType t,
   return v;
 }
 
+static mlir::Value emitSignBit(mlir::Location loc, CIRGenFunction &cgf,
+                               mlir::Value val) {
+  assert(!::cir::MissingFeatures::isPPC_FP128Ty());
+  cir::SignBitOp returnValue = cgf.getBuilder().createSignBit(loc, val);
+  return returnValue->getResult(0);
+}
+
 static Address checkAtomicAlignment(CIRGenFunction &cgf, const CallExpr *e) {
   ASTContext &astContext = cgf.getContext();
   Address ptr = cgf.emitPointerWithAlignment(e->getArg(0));
@@ -1540,7 +1547,23 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
   case Builtin::BI__builtin_masked_store:
   case Builtin::BI__builtin_masked_compress_store:
   case Builtin::BI__builtin_masked_scatter:
-  case Builtin::BI__builtin_isinf_sign:
+    return errorBuiltinNYI(*this, e, builtinID);
+  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 isInf =
+        builder.createIsFPClass(loc, arg, cir::FPClassTest::Infinity);
+    mlir::Value isNeg = emitSignBit(loc, *this, arg);
+    mlir::Type intTy = convertType(e->getType());
+    cir::ConstantOp zero = builder.getNullValue(intTy, loc);
+    cir::ConstantOp one = builder.getConstant(loc, cir::IntAttr::get(intTy, 
1));
+    cir::ConstantOp negativeOne =
+        builder.getConstant(loc, cir::IntAttr::get(intTy, -1));
+    mlir::Value signResult = builder.createSelect(loc, isNeg, negativeOne, 
one);
+    mlir::Value result = builder.createSelect(loc, isInf, signResult, zero);
+    return RValue::get(result);
+  }
   case Builtin::BI__builtin_flt_rounds:
   case Builtin::BI__builtin_set_flt_rounds:
   case Builtin::BI__builtin_fpclassify:

diff  --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 37cc6c113ff89..accb60df3799e 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -838,6 +838,35 @@ mlir::LogicalResult 
CIRToLLVMIsFPClassOpLowering::matchAndRewrite(
   return mlir::success();
 }
 
+mlir::LogicalResult CIRToLLVMSignBitOpLowering::matchAndRewrite(
+    cir::SignBitOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  assert(!cir::MissingFeatures::isPPC_FP128Ty());
+
+  mlir::DataLayout layout(op->getParentOfType<mlir::ModuleOp>());
+  int width = layout.getTypeSizeInBits(op.getInput().getType());
+  if (auto longDoubleType =
+          mlir::dyn_cast<cir::LongDoubleType>(op.getInput().getType())) {
+    if (mlir::isa<cir::FP80Type>(longDoubleType.getUnderlying())) {
+      // If the underlying type of LongDouble is FP80Type,
+      // DataLayout::getTypeSizeInBits returns 128.
+      // See https://github.com/llvm/clangir/issues/1057.
+      // Set the width to 80 manually.
+      width = 80;
+    }
+  }
+  mlir::Type intTy = mlir::IntegerType::get(rewriter.getContext(), width);
+  auto bitcast = mlir::LLVM::BitcastOp::create(rewriter, op->getLoc(), intTy,
+                                               adaptor.getInput());
+
+  auto zero = mlir::LLVM::ConstantOp::create(rewriter, op->getLoc(), intTy, 0);
+  auto cmpResult = mlir::LLVM::ICmpOp::create(rewriter, op.getLoc(),
+                                              mlir::LLVM::ICmpPredicate::slt,
+                                              bitcast.getResult(), zero);
+  rewriter.replaceOp(op, cmpResult);
+  return mlir::success();
+}
+
 mlir::LogicalResult CIRToLLVMAssumeOpLowering::matchAndRewrite(
     cir::AssumeOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {

diff  --git a/clang/test/CIR/CodeGenBuiltins/builtin-isinf-sign.c 
b/clang/test/CIR/CodeGenBuiltins/builtin-isinf-sign.c
new file mode 100644
index 0000000000000..27c6730ca996a
--- /dev/null
+++ b/clang/test/CIR/CodeGenBuiltins/builtin-isinf-sign.c
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o 
%t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o 
%t.cir.ll
+// RUN: FileCheck --input-file=%t.cir.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+
+int test_float_isinf_sign(float x) {
+  // CIR-LABEL: test_float_isinf_sign
+  // CIR: %[[ARG:.*]] = cir.load align(4) %{{.*}} : !cir.ptr<!cir.float>, 
!cir.float
+  // CIR: %[[IS_INF:.*]] = cir.is_fp_class %[[ARG]], fcInf : (!cir.float) -> 
!cir.bool
+  // CIR: %[[IS_NEG:.*]] = cir.signbit %[[ARG]] : !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: %[[SIGN:.*]] = cir.select if %[[IS_NEG]] then %[[C_m1]] else 
%[[C_1]] : (!cir.bool, !s32i, !s32i) -> !s32i
+  // CIR: %[[RET:.*]] = cir.select if %[[IS_INF]] then %[[SIGN]] else %[[C_0]] 
: (!cir.bool, !s32i, !s32i) -> !s32i
+  // CIR: cir.store %[[RET]], %{{.*}} : !s32i, !cir.ptr<!s32i>
+
+  // LLVM-LABEL: test_float_isinf_sign
+  // LLVM: %[[ARG:.*]] = load float, ptr %{{.*}}
+  // LLVM: %[[IS_INF:.*]] = call i1 @llvm.is.fpclass.f32(float %[[ARG]], i32 
516)
+  // LLVM: %[[BITCAST:.*]] = bitcast float %[[ARG]] to i32
+  // LLVM: %[[IS_NEG:.*]] = icmp slt i32 %[[BITCAST]], 0
+  // LLVM: %[[SIGN:.*]] = select i1 %[[IS_NEG]], i32 -1, i32 1
+  // LLVM: %[[RET:.*]] = select i1 %[[IS_INF]], i32 %[[SIGN]], i32 0
+  // LLVM: store i32 %[[RET]], ptr %{{.*}}, align 4
+
+  // OGCG-LABEL: test_float_isinf_sign
+  // OGCG: %[[ARG:.*]] = load float, ptr %{{.*}}
+  // OGCG: %[[ABS:.*]] = call float @llvm.fabs.f32(float %[[ARG]])
+  // OGCG: %[[IS_INF:.*]] = fcmp oeq float %[[ABS]], 0x7FF0000000000000
+  // OGCG: %[[BITCAST:.*]] = bitcast float %[[ARG]] to i32
+  // OGCG: %[[IS_NEG:.*]] = icmp slt i32 %[[BITCAST]], 0
+  // OGCG: %[[SIGN:.*]] = select i1 %[[IS_NEG]], i32 -1, i32 1
+  // OGCG: %[[RET:.*]] = select i1 %[[IS_INF]], i32 %[[SIGN]], i32 0
+  // OGCG: ret i32 %[[RET]]
+  return __builtin_isinf_sign(x);
+}


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to