================
@@ -3733,6 +3733,210 @@ RValue CodeGenFunction::EmitBuiltinExpr(const 
GlobalDecl GD, unsigned BuiltinID,
   case Builtin::BI_rotr64:
     return emitRotate(E, true);
 
+  case Builtin::BI__builtin_stdc_leading_zeros: {
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+    llvm::Type *ArgType = ArgValue->getType();
+    llvm::Type *ResultType = ConvertType(E->getType());
+    Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
+    Value *Result = Builder.CreateCall(F, {ArgValue, Builder.getFalse()});
+    if (Result->getType() != ResultType)
+      Result = Builder.CreateIntCast(Result, ResultType, false);
+    return RValue::get(Result);
+  }
+  case Builtin::BI__builtin_stdc_leading_ones: {
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+    llvm::Type *ArgType = ArgValue->getType();
+    llvm::Type *ResultType = ConvertType(E->getType());
+    Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
+    Value *Result = Builder.CreateCall(
+        F, {Builder.CreateNot(ArgValue), Builder.getFalse()});
+    if (Result->getType() != ResultType)
+      Result = Builder.CreateIntCast(Result, ResultType, false);
+    return RValue::get(Result);
+  }
+  case Builtin::BI__builtin_stdc_trailing_zeros: {
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+    llvm::Type *ArgType = ArgValue->getType();
+    llvm::Type *ResultType = ConvertType(E->getType());
+    Function *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
+    Value *Result = Builder.CreateCall(F, {ArgValue, Builder.getFalse()});
+    if (Result->getType() != ResultType)
+      Result = Builder.CreateIntCast(Result, ResultType, false);
+    return RValue::get(Result);
+  }
+  case Builtin::BI__builtin_stdc_trailing_ones: {
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+    llvm::Type *ArgType = ArgValue->getType();
+    llvm::Type *ResultType = ConvertType(E->getType());
+    Function *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
+    Value *Result = Builder.CreateCall(
+        F, {Builder.CreateNot(ArgValue), Builder.getFalse()});
+    if (Result->getType() != ResultType)
+      Result = Builder.CreateIntCast(Result, ResultType, false);
+    return RValue::get(Result);
+  }
+  case Builtin::BI__builtin_stdc_first_leading_zero: {
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+    llvm::Type *ArgType = ArgValue->getType();
+    llvm::Type *ResultType = ConvertType(E->getType());
+    Value *Zero = ConstantInt::get(ArgType, 0);
+    Value *One = ConstantInt::get(ArgType, 1);
+    Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
+    Value *Cnt = Builder.CreateCall(
+        F, {Builder.CreateNot(ArgValue), Builder.getFalse()});
+    Value *Tmp = Builder.CreateAdd(Cnt, One);
+    Value *IsAllOnes =
+        Builder.CreateICmpEQ(ArgValue, Constant::getAllOnesValue(ArgType));
+    Value *Result = Builder.CreateSelect(IsAllOnes, Zero, Tmp);
+    if (Result->getType() != ResultType)
+      Result = Builder.CreateIntCast(Result, ResultType, false);
+    return RValue::get(Result);
+  }
+  case Builtin::BI__builtin_stdc_first_leading_one: {
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+    llvm::Type *ArgType = ArgValue->getType();
+    llvm::Type *ResultType = ConvertType(E->getType());
+    Value *Zero = ConstantInt::get(ArgType, 0);
+    Value *One = ConstantInt::get(ArgType, 1);
+    Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
+    Value *Cnt = Builder.CreateCall(F, {ArgValue, Builder.getFalse()});
+    Value *Tmp = Builder.CreateAdd(Cnt, One);
+    Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero);
+    Value *Result = Builder.CreateSelect(IsZero, Zero, Tmp);
+    if (Result->getType() != ResultType)
+      Result = Builder.CreateIntCast(Result, ResultType, false);
+    return RValue::get(Result);
+  }
+  case Builtin::BI__builtin_stdc_first_trailing_zero: {
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+    llvm::Type *ArgType = ArgValue->getType();
+    llvm::Type *ResultType = ConvertType(E->getType());
+    Value *Zero = ConstantInt::get(ArgType, 0);
+    Value *One = ConstantInt::get(ArgType, 1);
+    Function *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
+    Value *Cnt = Builder.CreateCall(
+        F, {Builder.CreateNot(ArgValue), Builder.getFalse()});
+    Value *Tmp = Builder.CreateAdd(Cnt, One);
+    Value *IsAllOnes =
+        Builder.CreateICmpEQ(ArgValue, Constant::getAllOnesValue(ArgType));
+    Value *Result = Builder.CreateSelect(IsAllOnes, Zero, Tmp);
+    if (Result->getType() != ResultType)
+      Result = Builder.CreateIntCast(Result, ResultType, false);
+    return RValue::get(Result);
+  }
+  case Builtin::BI__builtin_stdc_first_trailing_one: {
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+    llvm::Type *ArgType = ArgValue->getType();
+    llvm::Type *ResultType = ConvertType(E->getType());
+    Value *Zero = ConstantInt::get(ArgType, 0);
+    Value *One = ConstantInt::get(ArgType, 1);
+    Function *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
+    Value *Cnt = Builder.CreateCall(F, {ArgValue, Builder.getFalse()});
+    Value *Tmp = Builder.CreateAdd(Cnt, One);
+    Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero);
+    Value *Result = Builder.CreateSelect(IsZero, Zero, Tmp);
+    if (Result->getType() != ResultType)
+      Result = Builder.CreateIntCast(Result, ResultType, false);
+    return RValue::get(Result);
+  }
+  case Builtin::BI__builtin_stdc_count_zeros: {
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+    llvm::Type *ArgType = ArgValue->getType();
+    llvm::Type *ResultType = ConvertType(E->getType());
+    unsigned BitWidth = ArgType->getIntegerBitWidth();
+    Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType);
+    Value *PopCnt = Builder.CreateCall(F, ArgValue);
+    Value *Result =
+        Builder.CreateSub(ConstantInt::get(ArgType, BitWidth), PopCnt);
+    if (Result->getType() != ResultType)
+      Result = Builder.CreateIntCast(Result, ResultType, false);
+    return RValue::get(Result);
+  }
+  case Builtin::BI__builtin_stdc_count_ones: {
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+    llvm::Type *ArgType = ArgValue->getType();
+    llvm::Type *ResultType = ConvertType(E->getType());
+    Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType);
+    Value *Result = Builder.CreateCall(F, ArgValue);
+    if (Result->getType() != ResultType)
+      Result = Builder.CreateIntCast(Result, ResultType, false);
+    return RValue::get(Result);
+  }
+  case Builtin::BI__builtin_stdc_has_single_bit: {
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+    llvm::Type *ArgType = ArgValue->getType();
+    Value *One = ConstantInt::get(ArgType, 1);
+    Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType);
+    Value *PopCnt = Builder.CreateCall(F, ArgValue);
+    return RValue::get(Builder.CreateICmpEQ(PopCnt, One));
+  }
+  case Builtin::BI__builtin_stdc_bit_width: {
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+    llvm::Type *ArgType = ArgValue->getType();
+    llvm::Type *ResultType = ConvertType(E->getType());
+    unsigned BitWidth = ArgType->getIntegerBitWidth();
+    Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
+    Value *LZ = Builder.CreateCall(F, {ArgValue, Builder.getFalse()});
+    Value *Result = Builder.CreateSub(ConstantInt::get(ArgType, BitWidth), LZ);
+    if (Result->getType() != ResultType)
+      Result = Builder.CreateIntCast(Result, ResultType, false);
+    return RValue::get(Result);
+  }
+  case Builtin::BI__builtin_stdc_bit_floor: {
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+    llvm::Type *ArgType = ArgValue->getType();
+    unsigned BitWidth = ArgType->getIntegerBitWidth();
+    Value *Zero = ConstantInt::get(ArgType, 0);
+    Value *One = ConstantInt::get(ArgType, 1);
+    Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
+    Value *LZ = Builder.CreateCall(F, {ArgValue, Builder.getTrue()});
+    Value *ShiftAmt =
+        Builder.CreateSub(ConstantInt::get(ArgType, BitWidth - 1), LZ);
+    Value *Shifted = Builder.CreateShl(One, ShiftAmt);
+    Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero);
+    Value *Result = Builder.CreateSelect(IsZero, Zero, Shifted);
+    return RValue::get(Result);
+  }
+  case Builtin::BI__builtin_stdc_bit_ceil: {
+    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+    llvm::Type *ArgType = ArgValue->getType();
+    unsigned BitWidth = ArgType->getIntegerBitWidth();
+    Value *Zero = ConstantInt::get(ArgType, 0);
+    Value *One = ConstantInt::get(ArgType, 1);
+
+    if (auto *CI = dyn_cast<ConstantInt>(ArgValue)) {
----------------
efriedma-quic wrote:

What's the point of special-casing constants?  LLVM transforms can 
constant-fold anyway.

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

Reply via email to