@@ -66,15 +66,48 @@ bool isLegalShaderModel(Triple &T) {
66
66
return false ;
67
67
}
68
68
69
- std::optional<std::string> tryParseProfile (StringRef Profile) {
70
- // [ps|vs|gs|hs|ds|cs|ms|as]_[major]_[minor]
69
+ struct ShaderModel {
70
+ StringRef TargetKind;
71
+ unsigned Major;
72
+ unsigned Minor;
73
+ bool OfflineLibMinor = false ;
74
+ };
75
+
76
+ std::optional<ShaderModel> GetShaderModelFromString (StringRef Profile) {
71
77
SmallVector<StringRef, 3 > Parts;
72
78
Profile.split (Parts, " _" );
73
79
if (Parts.size () != 3 )
74
80
return std::nullopt;
75
81
82
+ unsigned long long Major = 0 ;
83
+ if (llvm::getAsUnsignedInteger (Parts[1 ], 0 , Major))
84
+ return std::nullopt;
85
+
86
+ unsigned long long Minor = 0 ;
87
+ bool isOfflineLibMinor = false ;
88
+ if (Parts[0 ] == " lib" && Parts[2 ] == " x" )
89
+ isOfflineLibMinor = true ;
90
+ else if (llvm::getAsUnsignedInteger (Parts[2 ], 0 , Minor))
91
+ return std::nullopt;
92
+
93
+ ShaderModel ret;
94
+ ret.TargetKind = Parts[0 ];
95
+ ret.Major = Major;
96
+ ret.Minor = Minor;
97
+ ret.OfflineLibMinor = isOfflineLibMinor;
98
+
99
+ return ret;
100
+ }
101
+
102
+ std::optional<std::string> tryParseProfile (StringRef Profile) {
103
+ std::optional<ShaderModel> SM = GetShaderModelFromString (Profile);
104
+ if (!SM.has_value ()) {
105
+ return std::nullopt;
106
+ }
107
+ // [ps|vs|gs|hs|ds|cs|ms|as]_[major]_[minor]
108
+
76
109
Triple::EnvironmentType Kind =
77
- StringSwitch<Triple::EnvironmentType>(Parts[ 0 ] )
110
+ StringSwitch<Triple::EnvironmentType>(SM. value (). TargetKind )
78
111
.Case (" ps" , Triple::EnvironmentType::Pixel)
79
112
.Case (" vs" , Triple::EnvironmentType::Vertex)
80
113
.Case (" gs" , Triple::EnvironmentType::Geometry)
@@ -88,21 +121,11 @@ std::optional<std::string> tryParseProfile(StringRef Profile) {
88
121
if (Kind == Triple::EnvironmentType::UnknownEnvironment)
89
122
return std::nullopt;
90
123
91
- unsigned long long Major = 0 ;
92
- if (llvm::getAsUnsignedInteger (Parts[1 ], 0 , Major))
93
- return std::nullopt;
94
-
95
- unsigned long long Minor = 0 ;
96
- if (Parts[2 ] == " x" && Kind == Triple::EnvironmentType::Library)
97
- Minor = OfflineLibMinor;
98
- else if (llvm::getAsUnsignedInteger (Parts[2 ], 0 , Minor))
99
- return std::nullopt;
100
-
101
124
// dxil-unknown-shadermodel-hull
102
125
llvm::Triple T;
103
126
T.setArch (Triple::ArchType::dxil);
104
127
T.setOSName (Triple::getOSTypeName (Triple::OSType::ShaderModel).str () +
105
- VersionTuple (Major, Minor).getAsString ());
128
+ VersionTuple (SM. value (). Major , SM. value (). Minor ).getAsString ());
106
129
T.setEnvironment (Kind);
107
130
if (isLegalShaderModel (T))
108
131
return T.getTriple ();
@@ -256,6 +279,44 @@ HLSLToolChain::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
256
279
DAL->AddJoinedArg (nullptr , Opts.getOption (options::OPT_O), " 3" );
257
280
}
258
281
282
+ // FIXME: add validation for enable_16bit_types should be after HLSL 2018 and
283
+ // shader model 6.2.
284
+ // See: https://github.com/llvm/llvm-project/issues/57876
285
+ if (DAL->hasArg (options::OPT_fnative_half_type)) {
286
+
287
+ bool HVArgIsValid = true ;
288
+ bool TPArgIsValid = true ;
289
+
290
+ const StringRef HVArg =
291
+ DAL->getLastArgValue (options::OPT_std_EQ, " hlsl2021" );
292
+
293
+ const StringRef TPArg =
294
+ DAL->getLastArgValue (options::OPT_target_profile, " " );
295
+ std::optional<ShaderModel> parsedTargetProfile =
296
+ GetShaderModelFromString (TPArg);
297
+
298
+ unsigned long long HV_year;
299
+ StringRef HV_year_str = HVArg.drop_front (4 );
300
+ if (HV_year_str != " 202x" ) {
301
+ llvm::getAsUnsignedInteger (HV_year_str, 0 , HV_year);
302
+ if (HV_year < 2021 )
303
+ HVArgIsValid = false ;
304
+ }
305
+
306
+ if (!parsedTargetProfile.has_value ())
307
+ return DAL;
308
+ else {
309
+ if (parsedTargetProfile.value ().Major < 6 ||
310
+ (parsedTargetProfile.value ().Major == 6 &&
311
+ parsedTargetProfile.value ().Minor < 2 ))
312
+ TPArgIsValid = false ;
313
+ }
314
+
315
+ // if the HLSL Version is not at least 2021, or the shader model is not at
316
+ // least 6.2, then enable-16bit-types is an invalid flag.
317
+ if (!(HVArgIsValid && TPArgIsValid))
318
+ getDriver ().Diag (diag::err_drv_hlsl_enable_16bit_types_option_invalid);
319
+ }
259
320
return DAL;
260
321
}
261
322
0 commit comments