diff --git a/include/dxc/DXIL/DxilUtil.h b/include/dxc/DXIL/DxilUtil.h index 6825f0a900..73a362e492 100644 --- a/include/dxc/DXIL/DxilUtil.h +++ b/include/dxc/DXIL/DxilUtil.h @@ -152,6 +152,9 @@ namespace dxilutil { void ReplaceRawBufferLoad64Bit(llvm::Function *F, llvm::Type *EltTy, hlsl::OP *hlslOP); void ReplaceRawBufferStore64Bit(llvm::Function *F, llvm::Type *ETy, hlsl::OP *hlslOP); + + bool IsConvergentMarker(llvm::Value *V); + llvm::Value *GetConvergentSource(llvm::Value *V); } } diff --git a/include/dxc/HLSL/DxilConvergent.h b/include/dxc/HLSL/DxilConvergent.h deleted file mode 100644 index 4d3b533269..0000000000 --- a/include/dxc/HLSL/DxilConvergent.h +++ /dev/null @@ -1,19 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// // -// DxilConvergent.h // -// Copyright (C) Microsoft Corporation. All rights reserved. // -// This file is distributed under the University of Illinois Open Source // -// License. See LICENSE.TXT for details. // -// // -/////////////////////////////////////////////////////////////////////////////// -#pragma once - -namespace llvm { - class Value; - class Function; -} - -namespace hlsl { - bool IsConvergentMarker(llvm::Value *V); - llvm::Value *GetConvergentSource(llvm::Value *V); -} diff --git a/lib/DXIL/DxilUtil.cpp b/lib/DXIL/DxilUtil.cpp index 453231a36b..d8f78cf741 100644 --- a/lib/DXIL/DxilUtil.cpp +++ b/lib/DXIL/DxilUtil.cpp @@ -14,6 +14,7 @@ #include "dxc/DXIL/DxilUtil.h" #include "dxc/DXIL/DxilModule.h" #include "dxc/DXIL/DxilOperations.h" +#include "dxc/HLSL/DxilConvergentName.h" #include "dxc/Support/Global.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" @@ -1171,6 +1172,26 @@ void ReplaceRawBufferStore64Bit(llvm::Function *F, llvm::Type *ETy, hlsl::OP *hl } } +bool IsConvergentMarker(const char *Name) { + StringRef RName = Name; + return RName.startswith(kConvergentFunctionPrefix); +} + +bool IsConvergentMarker(const Function *F) { + return F && F->getName().startswith(kConvergentFunctionPrefix); +} + +bool IsConvergentMarker(Value *V) { + CallInst *CI = dyn_cast(V); + if (!CI) + return false; + return IsConvergentMarker(CI->getCalledFunction()); +} + +Value *GetConvergentSource(Value *V) { + return cast(V)->getOperand(0); +} + } } diff --git a/lib/HLSL/DxilConvergent.cpp b/lib/HLSL/DxilConvergent.cpp index ae67a5b387..bef8eee8e1 100644 --- a/lib/HLSL/DxilConvergent.cpp +++ b/lib/HLSL/DxilConvergent.cpp @@ -22,24 +22,13 @@ #include "dxc/HLSL/DxilGenerationPass.h" #include "dxc/HLSL/HLOperations.h" #include "dxc/HLSL/HLModule.h" -#include "dxc/HLSL/DxilConvergent.h" #include "dxc/HlslIntrinsicOp.h" #include "dxc/HLSL/DxilConvergentName.h" using namespace llvm; using namespace hlsl; -bool hlsl::IsConvergentMarker(Value *V) { - CallInst *CI = dyn_cast(V); - if (!CI) - return false; - Function *F = CI->getCalledFunction(); - return F->getName().startswith(kConvergentFunctionPrefix); -} -Value *hlsl::GetConvergentSource(Value *V) { - return cast(V)->getOperand(0); -} /////////////////////////////////////////////////////////////////////////////// // DxilConvergent. diff --git a/lib/HLSL/HLOperationLower.cpp b/lib/HLSL/HLOperationLower.cpp index 496eb287a7..85c63badf6 100644 --- a/lib/HLSL/HLOperationLower.cpp +++ b/lib/HLSL/HLOperationLower.cpp @@ -25,7 +25,6 @@ #include "dxc/HLSL/HLOperationLowerExtension.h" #include "dxc/HLSL/HLOperations.h" #include "dxc/HlslIntrinsicOp.h" -#include "dxc/HLSL/DxilConvergent.h" #include "dxc/DXIL/DxilResourceProperties.h" #include "llvm/IR/GetElementPtrTypeIterator.h" @@ -844,8 +843,8 @@ Value *FindScalarSource(Value *src, unsigned vecIdx = 0) { vecIdx = (unsigned)cast(EE->getIndexOperand()) ->getUniqueInteger().getLimitedValue(); src = EE->getVectorOperand(); - } else if (hlsl::IsConvergentMarker(src)) { - src = hlsl::GetConvergentSource(src); + } else if (hlsl::dxilutil::IsConvergentMarker(src)) { + src = hlsl::dxilutil::GetConvergentSource(src); } else { break; // Found it. } diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index 9633d771ba..49b7ea377c 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/lib/Transforms/Utils/Local.cpp @@ -46,6 +46,7 @@ #include "llvm/Support/raw_ostream.h" #include "dxc/DXIL/DxilMetadataHelper.h" // HLSL Change - combine dxil metadata. +#include "dxc/DXIL/DxilUtil.h" // HLSL Change - special handling of convergent marker using namespace llvm; #define DEBUG_TYPE "local" @@ -331,6 +332,10 @@ bool llvm::isInstructionTriviallyDead(Instruction *I, if (Constant *C = dyn_cast(CI->getArgOperand(0))) return C->isNullValue() || isa(C); + // HLSL change - don't force unused convergenet markers to stay + if (CallInst *CI = dyn_cast(I)) + if (hlsl::dxilutil::IsConvergentMarker(CI)) return true; + return false; } diff --git a/tools/clang/test/HLSLFileCheck/passes/llvm/dce/remove_convergent_marker.hlsl b/tools/clang/test/HLSLFileCheck/passes/llvm/dce/remove_convergent_marker.hlsl new file mode 100644 index 0000000000..cbc4d91f6d --- /dev/null +++ b/tools/clang/test/HLSLFileCheck/passes/llvm/dce/remove_convergent_marker.hlsl @@ -0,0 +1,20 @@ +// RUN: %dxc /T ps_6_0 %s | FileCheck %s + +// Tests that a convergent marker added by a derivative call +// is removed in time to let the rest of the dead code be removed + + +// Since everything is ignored, there should be no conditionals +// and just a single return void + +// CHECK: void @main +// CHECK-NOT: br +// CHECK: storeOutput +// CHECK: ret void + +float main(float d : DEPTH0) : SV_Target { + if (d > 0) + d = max(d, 3.0); + ddx(d+1); + return 0.0; +}