From a6ccc86cda44753991021a5c39be29d014cd4e29 Mon Sep 17 00:00:00 2001 From: Greg Roth Date: Mon, 29 Mar 2021 18:54:28 -0600 Subject: [PATCH] Allow removal of trivially dead convergent marker merge #3640 into release-1.6.2104 Failing to remove this because it is marked as having side effects so it can prevent unwanted code movement resulted in trivially dead code being retained unnecessarily because the marker isn't removed until after dead code elimination. By allowing its removal when the operation that needed it has been removed so it has no users, this dead code can be eliminated. (cherry picked from commit cf135fa88b79cb336129c3cd15845d31f2e2ddad) --- include/dxc/DXIL/DxilUtil.h | 3 +++ include/dxc/HLSL/DxilConvergent.h | 19 ----------------- lib/DXIL/DxilUtil.cpp | 21 +++++++++++++++++++ lib/HLSL/DxilConvergent.cpp | 11 ---------- lib/HLSL/HLOperationLower.cpp | 5 ++--- lib/Transforms/Utils/Local.cpp | 5 +++++ .../llvm/dce/remove_convergent_marker.hlsl | 20 ++++++++++++++++++ 7 files changed, 51 insertions(+), 33 deletions(-) delete mode 100644 include/dxc/HLSL/DxilConvergent.h create mode 100644 tools/clang/test/HLSLFileCheck/passes/llvm/dce/remove_convergent_marker.hlsl 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; +}