Repository: llvm/llvm-project
File: clang/lib/CodeGen/CGBuiltin.cpp (C++)

Code before:
        emitBuiltinWithOneOverloadedType<3>(*this, E, Intrinsic::fshr));

  case Builtin::BI__builtin_elementwise_add_sat:
  case Builtin::BI__builtin_elementwise_sub_sat: {
    Value *Op0 = EmitScalarExpr(E->getArg(0));
    Value *Op1 = EmitScalarExpr(E->getArg(1));
    Value *Result;
    assert(Op0->getType()->isIntOrIntVectorTy() && "integer type expected");
    QualType Ty = E->getArg(0)->getType();
    if (auto *VecTy = Ty->getAs<VectorType>())
      Ty = VecTy->getElementType();
    bool IsSigned = Ty->isSignedIntegerType();
    unsigned Opc;
    if (BuiltinIDIfNoAsmLabel == Builtin::BI__builtin_elementwise_add_sat)
      Opc = IsSigned ? Intrinsic::sadd_sat : Intrinsic::uadd_sat;
    else
      Opc = IsSigned ? Intrinsic::ssub_sat : Intrinsic::usub_sat;
    Result = Builder.CreateBinaryIntrinsic(Opc, Op0, Op1, nullptr, "elt.sat");
    return RValue::get(Result);
  }

  case Builtin::BI__builtin_elementwise_max: {
    Value *Op0 = EmitScalarExpr(E->getArg(0));
    Value *Op1 = EmitScalarExpr(E->getArg(1));
    Value *Result;
    assert(Op0->getType()->isIntOrIntVectorTy());
    QualType Ty = E->getArg(0)->getType();
    if (auto *VecTy = Ty->getAs<VectorType>())
      Ty = VecTy->getElementType();
    Result = Builder.CreateBinaryIntrinsic(
        Ty->isSignedIntegerType() ? Intrinsic::smax : Intrinsic::umax, Op0, Op1,
        nullptr, "elt.max");
    return RValue::get(Result);
  }
  case Builtin::BI__builtin_elementwise_min: {
    Value *Op0 = EmitScalarExpr(E->getArg(0));
    Value *Op1 = EmitScalarExpr(E->getArg(1));
    Value *Result;
    assert(Op0->getType()->isIntOrIntVectorTy());
    QualType Ty = E->getArg(0)->getType();
    if (auto *VecTy = Ty->getAs<VectorType>())
      Ty = VecTy->getElementType();
    Result = Builder.CreateBinaryIntrinsic(
        Ty->isSignedIntegerType() ? Intrinsic::smin : Intrinsic::umin, Op0, Op1,
        nullptr, "elt.min");
    return RValue::get(Result);
  }

  case Builtin::BI__builtin_elementwise_maxnum: {
    Value *Op0 = EmitScalarExpr(E->getArg(0));
    Value *Op1 = EmitScalarExpr(E->getArg(1));

Review comment (suggestion):
There should also be a change somewhere else that makes this an error at the Sema level. This can't just assert if you try to use it with floats, it needs to error cleanly.

Code after:
    return RValue::get(emitBuiltinWithOneOverloadedType<1>(
        *this, E, Intrinsic::bitreverse, "elt.bitreverse"));
  case Builtin::BI__builtin_elementwise_popcount:
    return RValue::get(emitBuiltinWithOneOverloadedType<1>(
        *this, E, Intrinsic::ctpop, "elt.ctpop"));
  case Builtin::BI__builtin_elementwise_canonicalize:
    return RValue::get(emitBuiltinWithOneOverloadedType<1>(
        *this, E, Intrinsic::canonicalize, "elt.canonicalize"));
  case Builtin::BI__builtin_elementwise_copysign:
    return RValue::get(
        emitBuiltinWithOneOverloadedType<2>(*this, E, Intrinsic::copysign));
  case Builtin::BI__builtin_elementwise_fshl:
    return RValue::get(
        emitBuiltinWithOneOverloadedType<3>(*this, E, Intrinsic::fshl));
  case Builtin::BI__builtin_elementwise_fshr:
    return RValue::get(
        emitBuiltinWithOneOverloadedType<3>(*this, E, Intrinsic::fshr));

  case Builtin::BI__builtin_elementwise_add_sat:
  case Builtin::BI__builtin_elementwise_sub_sat: {
    Value *Op0 = EmitScalarExpr(E->getArg(0));
    Value *Op1 = EmitScalarExpr(E->getArg(1));
    Value *Result;
    assert(Op0->getType()->isIntOrIntVectorTy() && "integer type expected");
    QualType Ty = E->getArg(0)->getType();
    if (auto *VecTy = Ty->getAs<VectorType>())
      Ty = VecTy->getElementType();
    bool IsSigned = Ty->isSignedIntegerType();
    unsigned Opc;
    if (BuiltinIDIfNoAsmLabel == Builtin::BI__builtin_elementwise_add_sat)
      Opc = IsSigned ? Intrinsic::sadd_sat : Intrinsic::uadd_sat;
    else
      Opc = IsSigned ? Intrinsic::ssub_sat : Intrinsic::usub_sat;
    Result = Builder.CreateBinaryIntrinsic(Opc, Op0, Op1, nullptr, "elt.sat");
    return RValue::get(Result);
  }

  case Builtin::BI__builtin_elementwise_max: {
    Value *Op0 = EmitScalarExpr(E->getArg(0));
    Value *Op1 = EmitScalarExpr(E->getArg(1));
    Value *Result;
    if (Op0->getType()->isIntOrIntVectorTy()) {
      QualType Ty = E->getArg(0)->getType();
      if (auto *VecTy = Ty->getAs<VectorType>())
        Ty = VecTy->getElementType();
      Result = Builder.CreateBinaryIntrinsic(
          Ty->isSignedIntegerType() ? Intrinsic::smax : Intrinsic::umax, Op0,
          Op1, nullptr, "elt.max");
    } else
      Result = Builder.CreateMaxNum(Op0, Op1, /*FMFSource=*/nullptr, "elt.max");
    return RValue::get(Result);