Skip to content

Commit f60cfd0

Browse files
committed
remove type promotion changes
1 parent 84b2e22 commit f60cfd0

File tree

6 files changed

+192
-204
lines changed

6 files changed

+192
-204
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10270,8 +10270,6 @@ def err_vec_builtin_non_vector : Error<
1027010270
"first two arguments to %0 must be vectors">;
1027110271
def err_vec_builtin_incompatible_vector : Error<
1027210272
"first two arguments to %0 must have the same type">;
10273-
def err_vec_builtin_incompatible_size : Error<
10274-
"first two arguments to %0 must have the same size">;
1027510273
def err_vsx_builtin_nonconstant_argument : Error<
1027610274
"argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">;
1027710275

@@ -12120,6 +12118,9 @@ def err_hlsl_param_qualifier_mismatch :
1212012118
def warn_hlsl_impcast_vector_truncation : Warning<
1212112119
"implicit conversion truncates vector: %0 to %1">, InGroup<Conversion>;
1212212120

12121+
def warn_hlsl_impcast_bitwidth_reduction : Warning<
12122+
"implicit conversion from larger type: %0 to smaller type %1, possible loss of data">, InGroup<Conversion>;
12123+
1212312124
// Layout randomization diagnostics.
1212412125
def err_non_designated_init_used : Error<
1212512126
"a randomized struct can only be initialized with a designated initializer">;

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17977,11 +17977,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
1797717977
llvm::Type *T1 = Op1->getType();
1797817978
if (!T0->isVectorTy() && !T1->isVectorTy()) {
1797917979
if (T0->isFloatingPointTy()) {
17980-
return Builder.CreateFMul(Op0, Op1, "dx.dot");
17980+
return Builder.CreateFMul(Op0, Op1, "dx.dot");
1798117981
}
1798217982

1798317983
if (T0->isIntegerTy()) {
17984-
return Builder.CreateMul(Op0, Op1, "dx.dot");
17984+
return Builder.CreateMul(Op0, Op1, "dx.dot");
1798517985
}
1798617986
// Bools should have been promoted
1798717987
assert(

clang/lib/Sema/SemaChecking.cpp

Lines changed: 61 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -5166,6 +5166,9 @@ bool Sema::CheckPPCMMAType(QualType Type, SourceLocation TypeLoc) {
51665166
return false;
51675167
}
51685168

5169+
// Helper function for CheckHLSLBuiltinFunctionCall
5170+
// Note: UsualArithmeticConversions handles the case where at least
5171+
// one arg isn't a bool
51695172
bool PromoteBoolsToInt(Sema *S, CallExpr *TheCall) {
51705173
unsigned NumArgs = TheCall->getNumArgs();
51715174

@@ -5181,47 +5184,13 @@ bool PromoteBoolsToInt(Sema *S, CallExpr *TheCall) {
51815184
Sema::AA_Converting);
51825185
if (ResA.isInvalid())
51835186
return true;
5184-
TheCall->setArg(0, ResA.get());
5187+
TheCall->setArg(i, ResA.get());
51855188
}
51865189
return false;
51875190
}
51885191

5189-
int overloadOrder(Sema *S, QualType ArgTyA) {
5190-
auto kind = ArgTyA->getAs<BuiltinType>()->getKind();
5191-
switch (kind) {
5192-
case BuiltinType::Short:
5193-
case BuiltinType::UShort:
5194-
return 1;
5195-
case BuiltinType::Int:
5196-
case BuiltinType::UInt:
5197-
return 2;
5198-
case BuiltinType::Long:
5199-
case BuiltinType::ULong:
5200-
return 3;
5201-
case BuiltinType::LongLong:
5202-
case BuiltinType::ULongLong:
5203-
return 4;
5204-
case BuiltinType::Float16:
5205-
case BuiltinType::Half:
5206-
return 5;
5207-
case BuiltinType::Float:
5208-
return 6;
5209-
default:
5210-
break;
5211-
}
5212-
return 0;
5213-
}
5214-
5215-
QualType getVecLargestBitness(Sema *S, QualType ArgTyA, QualType ArgTyB) {
5216-
auto *VecTyA = ArgTyA->getAs<VectorType>();
5217-
auto *VecTyB = ArgTyB->getAs<VectorType>();
5218-
QualType VecTyAElem = VecTyA->getElementType();
5219-
QualType VecTyBElem = VecTyB->getElementType();
5220-
int vecAElemWidth = overloadOrder(S, VecTyAElem);
5221-
int vecBElemWidth = overloadOrder(S, VecTyBElem);
5222-
return vecAElemWidth > vecBElemWidth ? ArgTyA : ArgTyB;
5223-
}
5224-
5192+
// Helper function for CheckHLSLBuiltinFunctionCall
5193+
// Handles the CK_HLSLVectorTruncation case for builtins
52255194
void PromoteVectorArgTruncation(Sema *S, CallExpr *TheCall) {
52265195
assert(TheCall->getNumArgs() > 1);
52275196
ExprResult A = TheCall->getArg(0);
@@ -5246,6 +5215,7 @@ void PromoteVectorArgTruncation(Sema *S, CallExpr *TheCall) {
52465215
SmallerArg = B.get();
52475216
largerIndex = 0;
52485217
}
5218+
52495219
S->Diag(TheCall->getExprLoc(), diag::warn_hlsl_impcast_vector_truncation)
52505220
<< LargerArg->getType() << SmallerArg->getType()
52515221
<< LargerArg->getSourceRange() << SmallerArg->getSourceRange();
@@ -5255,61 +5225,79 @@ void PromoteVectorArgTruncation(Sema *S, CallExpr *TheCall) {
52555225
return;
52565226
}
52575227

5258-
bool PromoteVectorElementCallArgs(Sema *S, CallExpr *TheCall) {
5228+
// Helper function for CheckHLSLBuiltinFunctionCall
5229+
void CheckVectorFloatPromotion(Sema *S, ExprResult &source, QualType targetTy,
5230+
SourceRange targetSrcRange,
5231+
SourceLocation BuiltinLoc) {
5232+
auto *vecTyTarget = source.get()->getType()->getAs<VectorType>();
5233+
assert(vecTyTarget);
5234+
QualType vecElemT = vecTyTarget->getElementType();
5235+
if (!vecElemT->isFloatingType() && targetTy->isFloatingType()) {
5236+
QualType floatVecTy = S->Context.getVectorType(
5237+
S->Context.FloatTy, vecTyTarget->getNumElements(), VectorKind::Generic);
5238+
int floatByteSize =
5239+
S->Context.getTypeSizeInChars(S->Context.FloatTy).getQuantity();
5240+
int vecElemByteSize = S->Context.getTypeSizeInChars(vecElemT).getQuantity();
5241+
if (vecElemByteSize > floatByteSize)
5242+
S->Diag(BuiltinLoc, diag::warn_hlsl_impcast_bitwidth_reduction)
5243+
<< source.get()->getType() << floatVecTy
5244+
<< source.get()->getSourceRange() << targetSrcRange;
5245+
5246+
source = S->SemaConvertVectorExpr(
5247+
source.get(), S->Context.CreateTypeSourceInfo(floatVecTy), BuiltinLoc,
5248+
source.get()->getBeginLoc());
5249+
}
5250+
}
5251+
5252+
// Helper function for CheckHLSLBuiltinFunctionCall
5253+
void PromoteVectorArgSplat(Sema *S, ExprResult &source, QualType targetTy) {
5254+
QualType sourceTy = source.get()->getType();
5255+
auto *vecTyTarget = targetTy->getAs<VectorType>();
5256+
QualType vecElemT = vecTyTarget->getElementType();
5257+
if (vecElemT->isFloatingType() && sourceTy != vecElemT)
5258+
// if float vec splat wil do an unnecessary cast to double
5259+
source = S->ImpCastExprToType(source.get(), vecElemT, CK_FloatingCast);
5260+
source = S->ImpCastExprToType(source.get(), targetTy, CK_VectorSplat);
5261+
}
5262+
5263+
// Helper function for CheckHLSLBuiltinFunctionCall
5264+
bool CheckVectorElementCallArgs(Sema *S, CallExpr *TheCall) {
52595265
assert(TheCall->getNumArgs() > 1);
52605266
ExprResult A = TheCall->getArg(0);
52615267
ExprResult B = TheCall->getArg(1);
52625268
QualType ArgTyA = A.get()->getType();
52635269
QualType ArgTyB = B.get()->getType();
5264-
52655270
auto *VecTyA = ArgTyA->getAs<VectorType>();
52665271
auto *VecTyB = ArgTyB->getAs<VectorType>();
5272+
52675273
if (VecTyA == nullptr && VecTyB == nullptr)
52685274
return false;
5275+
52695276
if (VecTyA && VecTyB) {
52705277
if (VecTyA->getElementType() == VecTyB->getElementType()) {
52715278
TheCall->setType(VecTyA->getElementType());
52725279
return false;
52735280
}
5274-
SourceLocation BuiltinLoc = TheCall->getBeginLoc();
5275-
QualType CastType = getVecLargestBitness(S, ArgTyA, ArgTyB);
5276-
if (CastType == ArgTyA) {
5277-
ExprResult ResB = S->SemaConvertVectorExpr(
5278-
B.get(), S->Context.CreateTypeSourceInfo(ArgTyA), BuiltinLoc,
5279-
B.get()->getBeginLoc());
5280-
TheCall->setArg(1, ResB.get());
5281-
TheCall->setType(VecTyA->getElementType());
5282-
return false;
5283-
}
5284-
5285-
if (CastType == ArgTyB) {
5286-
ExprResult ResA = S->SemaConvertVectorExpr(
5287-
A.get(), S->Context.CreateTypeSourceInfo(ArgTyB), BuiltinLoc,
5288-
A.get()->getBeginLoc());
5289-
TheCall->setArg(0, ResA.get());
5290-
TheCall->setType(VecTyB->getElementType());
5291-
return false;
5292-
}
5293-
return false;
5281+
// Note: type promotion is intended to be handeled via the intrinsics
5282+
// and not the builtin itself.
5283+
S->Diag(TheCall->getBeginLoc(), diag::err_vec_builtin_incompatible_vector)
5284+
<< TheCall->getDirectCallee()
5285+
<< SourceRange(A.get()->getBeginLoc(), B.get()->getEndLoc());
5286+
return true;
52945287
}
52955288

52965289
if (VecTyB) {
5297-
// Convert to the vector result type
5298-
ExprResult ResA = A;
5299-
if (VecTyB->getElementType() != ArgTyA)
5300-
ResA = S->ImpCastExprToType(ResA.get(), VecTyB->getElementType(),
5301-
CK_FloatingCast);
5302-
ResA = S->ImpCastExprToType(ResA.get(), ArgTyB, CK_VectorSplat);
5303-
TheCall->setArg(0, ResA.get());
5290+
CheckVectorFloatPromotion(S, B, ArgTyA, A.get()->getSourceRange(),
5291+
TheCall->getBeginLoc());
5292+
PromoteVectorArgSplat(S, A, B.get()->getType());
53045293
}
53055294
if (VecTyA) {
5306-
ExprResult ResB = B;
5307-
if (VecTyA->getElementType() != ArgTyB)
5308-
ResB = S->ImpCastExprToType(ResB.get(), VecTyA->getElementType(),
5309-
CK_FloatingCast);
5310-
ResB = S->ImpCastExprToType(ResB.get(), ArgTyA, CK_VectorSplat);
5311-
TheCall->setArg(1, ResB.get());
5295+
CheckVectorFloatPromotion(S, A, ArgTyB, B.get()->getSourceRange(),
5296+
TheCall->getBeginLoc());
5297+
PromoteVectorArgSplat(S, B, A.get()->getType());
53125298
}
5299+
TheCall->setArg(0, A.get());
5300+
TheCall->setArg(1, B.get());
53135301
return false;
53145302
}
53155303

@@ -5322,7 +5310,7 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
53225310
return true;
53235311
if (PromoteBoolsToInt(this, TheCall))
53245312
return true;
5325-
if (PromoteVectorElementCallArgs(this, TheCall))
5313+
if (CheckVectorElementCallArgs(this, TheCall))
53265314
return true;
53275315
PromoteVectorArgTruncation(this, TheCall);
53285316
if (SemaBuiltinVectorToScalarMath(TheCall))
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
2+
// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
3+
// RUN: -emit-llvm -disable-llvm-passes -O3 -o - | FileCheck %s \
4+
// RUN: --check-prefixes=CHECK
5+
6+
// CHECK: %dx.dot = call float @llvm.dx.dot.v2f32(<2 x float> %splat.splat, <2 x float> %1)
7+
// CHECK: ret float %dx.dot
8+
float test_builtin_dot_float2_splat ( float p0, float2 p1 ) {
9+
return __builtin_hlsl_dot( p0, p1 );
10+
}
11+
12+
// CHECK: %dx.dot = call float @llvm.dx.dot.v3f32(<3 x float> %splat.splat, <3 x float> %1)
13+
// CHECK: ret float %dx.dot
14+
float test_builtin_dot_float3_splat ( float p0, float3 p1 ) {
15+
return __builtin_hlsl_dot( p0, p1 );
16+
}
17+
18+
// CHECK: %dx.dot = call float @llvm.dx.dot.v4f32(<4 x float> %splat.splat, <4 x float> %1)
19+
// CHECK: ret float %dx.dot
20+
float test_builtin_dot_float4_splat ( float p0, float4 p1 ) {
21+
return __builtin_hlsl_dot( p0, p1 );
22+
}
23+
24+
// CHECK: %conv = sitofp i32 %1 to float
25+
// CHECK: %splat.splatinsert = insertelement <2 x float> poison, float %conv, i64 0
26+
// CHECK: %splat.splat = shufflevector <2 x float> %splat.splatinsert, <2 x float> poison, <2 x i32> zeroinitializer
27+
// CHECK: %dx.dot = call float @llvm.dx.dot.v2f32(<2 x float> %0, <2 x float> %splat.splat)
28+
// CHECK: ret float %dx.dot
29+
float test_dot_float2_int_splat ( float2 p0, int p1 ) {
30+
return __builtin_hlsl_dot ( p0, p1 );
31+
}
32+
33+
// CHECK: %conv = sitofp i32 %1 to float
34+
// CHECK: %splat.splatinsert = insertelement <3 x float> poison, float %conv, i64 0
35+
// CHECK: %splat.splat = shufflevector <3 x float> %splat.splatinsert, <3 x float> poison, <3 x i32> zeroinitializer
36+
// CHECK: %dx.dot = call float @llvm.dx.dot.v3f32(<3 x float> %0, <3 x float> %splat.splat)
37+
// CHECK: ret float %dx.dot
38+
float test_dot_float3_int_splat ( float3 p0, int p1 ) {
39+
return __builtin_hlsl_dot ( p0, p1 );
40+
}
41+
42+
// CHECK: %conv1 = uitofp i1 %tobool to double
43+
// CHECK: %dx.dot = fmul double %conv, %conv1
44+
// CHECK: %conv2 = fptrunc double %dx.dot to float
45+
// CHECK: ret float %conv2
46+
float builtin_bool_to_float_type_promotion ( float p0, bool p1 ) {
47+
return __builtin_hlsl_dot ( p0, p1 );
48+
}
49+
50+
// CHECK: %conv = uitofp i1 %tobool to double
51+
// CHECK: %conv1 = fpext float %1 to double
52+
// CHECK: %dx.dot = fmul double %conv, %conv1
53+
// CHECK: %conv2 = fptrunc double %dx.dot to float
54+
// CHECK: ret float %conv2
55+
float builtin_bool_to_float_arg1_type_promotion ( bool p0, float p1 ) {
56+
return __builtin_hlsl_dot ( p0, p1 );
57+
}
58+
59+
// CHECK: %conv = zext i1 %tobool to i32
60+
// CHECK: %conv3 = zext i1 %tobool2 to i32
61+
// CHECK: %dx.dot = mul i32 %conv, %conv3
62+
// CHECK: ret i32 %dx.dot
63+
int test_builtin_dot_bool_type_promotion ( bool p0, bool p1 ) {
64+
return __builtin_hlsl_dot ( p0, p1 );
65+
}
66+
67+
// CHECK: %conv = fpext float %0 to double
68+
// CHECK: %conv1 = sitofp i32 %1 to double
69+
// CHECK: dx.dot = fmul double %conv, %conv1
70+
// CHECK: %conv2 = fptrunc double %dx.dot to float
71+
// CHECK: ret float %conv2
72+
float test_builtin_dot_int_to_float_promotion ( float p0, int p1 ) {
73+
return __builtin_hlsl_dot ( p0, p1 );
74+
}
75+
76+
77+
// CHECK: %conv = sitofp <2 x i32> %0 to <2 x float>
78+
// CHECK: %splat.splat = shufflevector <2 x float> %splat.splatinsert, <2 x float> poison, <2 x i32> zeroinitializer
79+
// CHECK: %dx.dot = call float @llvm.dx.dot.v2f32(<2 x float> %conv, <2 x float> %splat.splat)
80+
// CHECK: ret float %dx.dot
81+
float test_builtin_dot_int-vect_to_float_vec_promotion ( int2 p0, float p1 ) {
82+
return __builtin_hlsl_dot ( p0, p1 );
83+
}

0 commit comments

Comments
 (0)