diff --git a/lib/Transforms/Scalar/Float2Int.cpp b/lib/Transforms/Scalar/Float2Int.cpp index 5549de1b9c..e3beb07ba0 100644 --- a/lib/Transforms/Scalar/Float2Int.cpp +++ b/lib/Transforms/Scalar/Float2Int.cpp @@ -129,19 +129,25 @@ static Instruction::BinaryOps mapBinOpcode(unsigned Opcode) { // Find the roots - instructions that convert from the FP domain to // integer domain. +// findRoots updated from upstream to skip vectors void Float2Int::findRoots(Function &F, SmallPtrSet &Roots) { - for (auto &I : inst_range(F)) { - switch (I.getOpcode()) { - default: break; - case Instruction::FPToUI: - case Instruction::FPToSI: - Roots.insert(&I); - break; - case Instruction::FCmp: - if (mapFCmpPred(cast(&I)->getPredicate()) != - CmpInst::BAD_ICMP_PREDICATE) + for (BasicBlock &BB : F) { + for (Instruction &I : BB) { + if (isa(I.getType())) + continue; + switch (I.getOpcode()) { + default: + break; + case Instruction::FPToUI: + case Instruction::FPToSI: Roots.insert(&I); - break; + break; + case Instruction::FCmp: + if (mapFCmpPred(cast(&I)->getPredicate()) != + CmpInst::BAD_ICMP_PREDICATE) + Roots.insert(&I); + break; + } } } } @@ -400,7 +406,7 @@ bool Float2Int::validateAndTransform() { R.isFullSet() || R.isSignWrappedSet()) continue; assert(ConvertedToTy && "Must have set the convertedtoty by this point!"); - + // The number of bits required is the maximum of the upper and // lower limits, plus one so it can be signed. unsigned MinBW = std::max(R.getLower().getMinSignedBits(), diff --git a/tools/clang/test/HLSLFileCheck/hlsl/types/cast/cast8.hlsl b/tools/clang/test/HLSLFileCheck/hlsl/types/cast/cast8.hlsl new file mode 100644 index 0000000000..8dcfa5948f --- /dev/null +++ b/tools/clang/test/HLSLFileCheck/hlsl/types/cast/cast8.hlsl @@ -0,0 +1,26 @@ +// RUN: %dxc -T cs_6_9 -DFTYPE=float2 %s | FileCheck %s +// RUN: %dxc -T cs_6_9 -DFTYPE=half2 -enable-16bit-types %s | FileCheck %s + + +// https://github.com/microsoft/DirectXShaderCompiler/issues/7915 +// Test long vector casting between uint2 and float2 +// which would crash as reported by a user. + +// CHECK: call %dx.types.Handle @dx.op.createHandleFromBinding +// CHECK: fptoui +// CHECK: uitofp +// CHECK: fptoui +// CHECK: uitofp +// CHECK: call void @dx.op.rawBufferVectorStore + +RWStructuredBuffer input; +RWStructuredBuffer output; + +FTYPE f1(uint2 p) { return p; } +uint2 f2(FTYPE p) { return f1(p); } + +[numthreads(1,1,1)] +void main() +{ + output[0] = f2(input[0]); +}