[llvm-branch-commits] [clang] [llvm] [HLSL][RootSignature] Add parsing of floats for StaticSampler (PR #140181)
Justin Bogner via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue May 27 10:02:38 PDT 2025
================
@@ -821,22 +873,115 @@ std::optional<uint32_t> RootSignatureParser::handleUIntLiteral() {
PP.getSourceManager(), PP.getLangOpts(),
PP.getTargetInfo(), PP.getDiagnostics());
if (Literal.hadError)
- return true; // Error has already been reported so just return
+ return std::nullopt; // Error has already been reported so just return
- assert(Literal.isIntegerLiteral() && "IsNumberChar will only support digits");
+ assert(Literal.isIntegerLiteral() &&
+ "NumSpelling can only consist of digits");
- llvm::APSInt Val = llvm::APSInt(32, false);
+ llvm::APSInt Val = llvm::APSInt(32, /*IsUnsigned=*/true);
if (Literal.GetIntegerValue(Val)) {
// Report that the value has overflowed
PP.getDiagnostics().Report(CurToken.TokLoc,
diag::err_hlsl_number_literal_overflow)
- << 0 << CurToken.NumSpelling;
+ << /*integer type*/ 0 << /*is signed*/ 0;
return std::nullopt;
}
return Val.getExtValue();
}
+std::optional<int32_t> RootSignatureParser::handleIntLiteral(bool Negated) {
+ // Parse the numeric value and do semantic checks on its specification
+ clang::NumericLiteralParser Literal(CurToken.NumSpelling, CurToken.TokLoc,
+ PP.getSourceManager(), PP.getLangOpts(),
+ PP.getTargetInfo(), PP.getDiagnostics());
+ if (Literal.hadError)
+ return std::nullopt; // Error has already been reported so just return
+
+ assert(Literal.isIntegerLiteral() &&
+ "NumSpelling can only consist of digits");
+
+ llvm::APSInt Val = llvm::APSInt(32, /*IsUnsigned=*/true);
+ // GetIntegerValue will overwrite Val from the parsed Literal and return
+ // true if it overflows as a 32-bit unsigned int. Then check that it also
+ // doesn't overflow as a signed 32-bit int.
+ int64_t MaxMagnitude =
+ -static_cast<int64_t>(std::numeric_limits<int32_t>::min());
+ if (Literal.GetIntegerValue(Val) || MaxMagnitude < Val.getExtValue()) {
+ // Report that the value has overflowed
+ PP.getDiagnostics().Report(CurToken.TokLoc,
+ diag::err_hlsl_number_literal_overflow)
+ << /*integer type*/ 0 << /*is signed*/ 1;
+ return std::nullopt;
+ }
+
+ if (Negated)
+ Val = -Val;
+
+ return static_cast<int32_t>(Val.getExtValue());
+}
+
+std::optional<float> RootSignatureParser::handleFloatLiteral(bool Negated) {
+ // Parse the numeric value and do semantic checks on its specification
+ clang::NumericLiteralParser Literal(CurToken.NumSpelling, CurToken.TokLoc,
+ PP.getSourceManager(), PP.getLangOpts(),
+ PP.getTargetInfo(), PP.getDiagnostics());
+ if (Literal.hadError)
+ return std::nullopt; // Error has already been reported so just return
+
+ assert(Literal.isFloatingLiteral() &&
+ "NumSpelling consists only of [0-9.ef+-]. Any malformed NumSpelling "
+ "will be caught and reported by NumericLiteralParser.");
+
+ // DXC used `strtod` to convert the token string to a float which corresponds
+ // to:
+ auto DXCSemantics = llvm::APFloat::Semantics::S_IEEEdouble;
+ auto DXCRoundingMode = llvm::RoundingMode::NearestTiesToEven;
+
+ llvm::APFloat Val =
+ llvm::APFloat(llvm::APFloat::EnumToSemantics(DXCSemantics));
+ llvm::APFloat::opStatus Status = Literal.GetFloatValue(Val, DXCRoundingMode);
+
+ // Note: we do not error when opStatus::opInexact by itself as this just
+ // denotes that rounding occured but not that it is invalid
+ assert(!(Status & llvm::APFloat::opStatus::opInvalidOp) &&
+ "NumSpelling consists only of [0-9.ef+-]. Any malformed NumSpelling "
+ "will be caught and reported by NumericLiteralParser.");
+
+ assert(!(Status & llvm::APFloat::opStatus::opDivByZero) &&
+ "It is not possible for a division to be performed when "
+ "constructing an APFloat from a string");
+
+ if (Status & llvm::APFloat::opStatus::opUnderflow) {
+ // Report that the value has underflowed
+ PP.getDiagnostics().Report(CurToken.TokLoc,
+ diag::err_hlsl_number_literal_underflow);
+ return std::nullopt;
+ }
+
+ if (Status & llvm::APFloat::opStatus::opOverflow) {
+ // Report that the value has overflowed
+ PP.getDiagnostics().Report(CurToken.TokLoc,
+ diag::err_hlsl_number_literal_overflow)
+ << /*float type*/ 1;
+ return std::nullopt;
+ }
+
+ if (Negated)
+ Val = -Val;
+
+ double DoubleVal = Val.convertToDouble();
+ if (FLT_MAX < DoubleVal || DoubleVal < -FLT_MAX) {
----------------
bogner wrote:
Aha, this is what `float.h` was for. Please use `std::numeric_limits` instead, as you do elsewhere.
https://github.com/llvm/llvm-project/pull/140181
More information about the llvm-branch-commits
mailing list