return Call;
}
+/// Emit the computation of the sign bit for a floating point value. Returns
+/// the i1 sign bit value.
+static Value *EmitSignBit(CodeGenFunction &CGF, Value *V) {
+ LLVMContext &C = CGF.CGM.getLLVMContext();
+
+ llvm::Type *Ty = V->getType();
+ int Width = Ty->getPrimitiveSizeInBits();
+ llvm::Type *IntTy = llvm::IntegerType::get(C, Width);
+ V = CGF.Builder.CreateBitCast(V, IntTy);
+ if (Ty->isPPC_FP128Ty()) {
+ // The higher-order double comes first, and so we need to truncate the
+ // pair to extract the overall sign. The order of the pair is the same
+ // in both little- and big-Endian modes.
+ Width >>= 1;
+ IntTy = llvm::IntegerType::get(C, Width);
+ V = CGF.Builder.CreateTrunc(V, IntTy);
+ }
+ Value *Zero = llvm::Constant::getNullValue(IntTy);
+ return CGF.Builder.CreateICmpSLT(V, Zero);
+}
+
static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *Fn,
const CallExpr *E, llvm::Value *calleeValue) {
return CGF.EmitCall(E->getCallee()->getType(), calleeValue, E,
return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType())));
}
- // TODO: BI__builtin_isinf_sign
- // isinf_sign(x) -> isinf(x) ? (signbit(x) ? -1 : 1) : 0
+ case Builtin::BI__builtin_isinf_sign: {
+ // isinf_sign(x) -> fabs(x) == infinity ? (signbit(x) ? -1 : 1) : 0
+ Value *Arg = EmitScalarExpr(E->getArg(0));
+ Value *AbsArg = EmitFAbs(*this, Arg);
+ Value *IsInf = Builder.CreateFCmpOEQ(
+ AbsArg, ConstantFP::getInfinity(Arg->getType()), "isinf");
+ Value *IsNeg = EmitSignBit(*this, Arg);
+
+ llvm::Type *IntTy = ConvertType(E->getType());
+ Value *Zero = Constant::getNullValue(IntTy);
+ Value *One = ConstantInt::get(IntTy, 1);
+ Value *NegativeOne = ConstantInt::get(IntTy, -1);
+ Value *SignResult = Builder.CreateSelect(IsNeg, NegativeOne, One);
+ Value *Result = Builder.CreateSelect(IsInf, SignResult, Zero);
+ return RValue::get(Result);
+ }
case Builtin::BI__builtin_isnormal: {
// isnormal(x) --> x == x && fabsf(x) < infinity && fabsf(x) >= float_min
case Builtin::BI__builtin_signbit:
case Builtin::BI__builtin_signbitf:
case Builtin::BI__builtin_signbitl: {
- LLVMContext &C = CGM.getLLVMContext();
-
- Value *Arg = EmitScalarExpr(E->getArg(0));
- llvm::Type *ArgTy = Arg->getType();
- int ArgWidth = ArgTy->getPrimitiveSizeInBits();
- llvm::Type *ArgIntTy = llvm::IntegerType::get(C, ArgWidth);
- Value *BCArg = Builder.CreateBitCast(Arg, ArgIntTy);
- if (ArgTy->isPPC_FP128Ty()) {
- // The higher-order double comes first, and so we need to truncate the
- // pair to extract the overall sign. The order of the pair is the same
- // in both little- and big-Endian modes.
- ArgWidth >>= 1;
- ArgIntTy = llvm::IntegerType::get(C, ArgWidth);
- BCArg = Builder.CreateTrunc(BCArg, ArgIntTy);
- }
- Value *ZeroCmp = llvm::Constant::getNullValue(ArgIntTy);
- Value *Result = Builder.CreateICmpSLT(BCArg, ZeroCmp);
- return RValue::get(Builder.CreateZExt(Result, ConvertType(E->getType())));
+ return RValue::get(
+ Builder.CreateZExt(EmitSignBit(*this, EmitScalarExpr(E->getArg(0))),
+ ConvertType(E->getType())));
}
case Builtin::BI__builtin_annotation: {
llvm::Value *AnnVal = EmitScalarExpr(E->getArg(0));
P(fpclassify, (0, 1, 2, 3, 4, 1.0));
P(fpclassify, (0, 1, 2, 3, 4, 1.0f));
P(fpclassify, (0, 1, 2, 3, 4, 1.0l));
- // FIXME:
- // P(isinf_sign, (1.0));
Q(nan, (""));
Q(nanf, (""));
P(islessgreater, (1., 2.));
P(isunordered, (1., 2.));
+ P(isinf, (1.));
+ P(isinf_sign, (1.));
P(isnan, (1.));
// Bitwise & Numeric Functions
res = __builtin_isinf(D);
// CHECK: call double @llvm.fabs.f64(double
// CHECK: fcmp oeq double {{.*}}, 0x7FF0000000000000
-
+
res = __builtin_isinf(LD);
// CHECK: call x86_fp80 @llvm.fabs.f80(x86_fp80
// CHECK: fcmp oeq x86_fp80 {{.*}}, 0xK7FFF8000000000000000
-
+
+ res = __builtin_isinf_sign(F);
+ // CHECK: %[[ABS:.*]] = call float @llvm.fabs.f32(float %[[ARG:.*]])
+ // CHECK: %[[ISINF:.*]] = fcmp oeq float %[[ABS]], 0x7FF0000000000000
+ // CHECK: %[[BITCAST:.*]] = bitcast float %[[ARG]] to i32
+ // CHECK: %[[ISNEG:.*]] = icmp slt i32 %[[BITCAST]], 0
+ // CHECK: %[[SIGN:.*]] = select i1 %[[ISNEG]], i32 -1, i32 1
+ // CHECK: select i1 %[[ISINF]], i32 %[[SIGN]], i32 0
+
+ res = __builtin_isinf_sign(D);
+ // CHECK: %[[ABS:.*]] = call double @llvm.fabs.f64(double %[[ARG:.*]])
+ // CHECK: %[[ISINF:.*]] = fcmp oeq double %[[ABS]], 0x7FF0000000000000
+ // CHECK: %[[BITCAST:.*]] = bitcast double %[[ARG]] to i64
+ // CHECK: %[[ISNEG:.*]] = icmp slt i64 %[[BITCAST]], 0
+ // CHECK: %[[SIGN:.*]] = select i1 %[[ISNEG]], i32 -1, i32 1
+ // CHECK: select i1 %[[ISINF]], i32 %[[SIGN]], i32 0
+
+ res = __builtin_isinf_sign(LD);
+ // CHECK: %[[ABS:.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 %[[ARG:.*]])
+ // CHECK: %[[ISINF:.*]] = fcmp oeq x86_fp80 %[[ABS]], 0xK7FFF8000000000000000
+ // CHECK: %[[BITCAST:.*]] = bitcast x86_fp80 %[[ARG]] to i80
+ // CHECK: %[[ISNEG:.*]] = icmp slt i80 %[[BITCAST]], 0
+ // CHECK: %[[SIGN:.*]] = select i1 %[[ISNEG]], i32 -1, i32 1
+ // CHECK: select i1 %[[ISINF]], i32 %[[SIGN]], i32 0
+
res = __builtin_isfinite(F);
// CHECK: fcmp oeq float
// CHECK: call float @llvm.fabs.f32(float