Skip to content

Commit 0db66a3

Browse files
author
Greg Roth
authored
Give Asdouble some love (i64 cast and folding) (#3666)
The type of the overload allowed i64 and refused casts. As a result, if an i64 value was used, invalid code is produced leading to asserts or validation errors. Added support for folding when the params of asdouble are constants
1 parent 8a52bc5 commit 0db66a3

5 files changed

Lines changed: 49 additions & 3 deletions

File tree

lib/Analysis/DxilConstantFolding.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,20 @@ static Constant *ConstantFoldBinaryIntIntrinsic(OP::OpCode opcode, Type *Ty, Con
363363
return nullptr;
364364
}
365365

366+
// Constant fold MakeDouble
367+
static Constant *ConstantFoldMakeDouble(Type *Ty, const DxilIntrinsicOperands &IntrinsicOperands) {
368+
assert(IntrinsicOperands.Size() == 2);
369+
ConstantInt *Op1 = IntrinsicOperands.GetConstantInt(0);
370+
ConstantInt *Op2 = IntrinsicOperands.GetConstantInt(1);
371+
if (!Op1 || !Op2)
372+
return nullptr;
373+
uint64_t C1 = Op1->getZExtValue();
374+
uint64_t C2 = Op2->getZExtValue();
375+
uint64_t dbits = C2 << 32 | C1;
376+
double dval = *(double*)&dbits;
377+
return ConstantFP::get(Ty, dval);
378+
}
379+
366380
// Compute bit field extract for ibfe and ubfe.
367381
// The comptuation for ibfe and ubfe is the same except for the right shift,
368382
// which is an arithemetic shift for ibfe and logical shift for ubfe.
@@ -477,6 +491,8 @@ static Constant *ConstantFoldFPIntrinsic(OP::OpCode opcode, Type *Ty, const Dxil
477491
case OP::OpCodeClass::Dot3:
478492
case OP::OpCodeClass::Dot4:
479493
return ConstantFoldDot(opcode, Ty, IntrinsicOperands);
494+
case OP::OpCodeClass::MakeDouble:
495+
return ConstantFoldMakeDouble(Ty, IntrinsicOperands);
480496
}
481497

482498
return nullptr;
@@ -589,6 +605,7 @@ bool hlsl::CanConstantFoldCallTo(const Function *F) {
589605
case OP::OpCodeClass::Dot2:
590606
case OP::OpCodeClass::Dot3:
591607
case OP::OpCodeClass::Dot4:
608+
case OP::OpCodeClass::MakeDouble:
592609
return true;
593610
case OP::OpCodeClass::IsHelperLane: {
594611
const hlsl::ShaderModel *pSM =

tools/clang/lib/Sema/gen_intrin_main_tables_15.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -858,8 +858,8 @@ static const HLSL_INTRINSIC_ARGUMENT g_Intrinsics_Args124[] =
858858
static const HLSL_INTRINSIC_ARGUMENT g_Intrinsics_Args125[] =
859859
{
860860
{"asdouble", AR_QUAL_OUT, 0, LITEMPLATE_ANY, 0, LICOMPTYPE_DOUBLE, IA_R, IA_C},
861-
{"x", AR_QUAL_IN, 0, LITEMPLATE_ANY, 1, LICOMPTYPE_UINT_ONLY, IA_R, IA_C},
862-
{"y", AR_QUAL_IN, 0, LITEMPLATE_ANY, 2, LICOMPTYPE_UINT_ONLY, IA_R, IA_C},
861+
{"x", AR_QUAL_IN, 0, LITEMPLATE_ANY, 1, LICOMPTYPE_UINT, IA_R, IA_C},
862+
{"y", AR_QUAL_IN, 0, LITEMPLATE_ANY, 2, LICOMPTYPE_UINT, IA_R, IA_C},
863863
};
864864

865865
static const HLSL_INTRINSIC_ARGUMENT g_Intrinsics_Args126[] =
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
2+
3+
// Verify that constants provided to asdouble can be folded
4+
// CHECK-NOT: makeDouble
5+
// CHECK: splitDouble.f64(i32 102, double -1.000000e+00
6+
7+
8+
uint2 main() : SV_Target
9+
{
10+
double d = asdouble(0, 0xBFF00000);
11+
uint2 ret;
12+
asuint(d, ret.x, ret.y);
13+
return ret;
14+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
2+
3+
// Verify that i64 params to asdouble don't produce an invalid MakeDouble that takes i64
4+
// CHECK: call double @dx.op.makeDouble.f64(i32 101, i32
5+
// CHECK: SplitDouble
6+
7+
uint64_t i;
8+
9+
uint2 main() : SV_Target
10+
{
11+
double d = asdouble(i&0xFFFFFFFF, i >> 32);
12+
uint2 ret;
13+
asuint(d, ret.x, ret.y);
14+
return ret;
15+
}

utils/hct/gen_intrin_main.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ bool [[rn]] all(in any<> x);
9595
void [[]] AllMemoryBarrier() : syncallmemory_ug;
9696
void [[]] AllMemoryBarrierWithGroupSync() : syncgroupandallmemory_ug;
9797
bool [[rn]] any(in any<> x);
98-
double<> [[rn]] asdouble(in $match<0, 1> uint_only<> x, in $match<0, 2> uint_only<> y) : reinterpret_fuse_double;
98+
double<> [[rn]] asdouble(in $match<0, 1> uint<> x, in $match<0, 2> uint<> y) : reinterpret_fuse_double;
9999
float<> [[rn]] asfloat(in $match<0, 1> numeric32_only<> x) : reinterpret_float;
100100
float16_t<> [[rn]] asfloat16(in $match<0,1> numeric16_only<> x) : reinterpret_float16;
101101
int16_t<> [[rn]] asint16(in $match<0,1> numeric16_only<> x) : reinterpret_int16;

0 commit comments

Comments
 (0)