[llvm] 6599fda - Add DXILPrepare CodeGen pass

Chris Bieneman via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 5 09:50:27 PDT 2022


Author: Chris Bieneman
Date: 2022-04-05T11:50:07-05:00
New Revision: 6599fdab2cd4f76021f560edcedbe396fd97216d

URL: https://github.com/llvm/llvm-project/commit/6599fdab2cd4f76021f560edcedbe396fd97216d
DIFF: https://github.com/llvm/llvm-project/commit/6599fdab2cd4f76021f560edcedbe396fd97216d.diff

LOG: Add DXILPrepare CodeGen pass

The DXIL Prepare pass handles the IR mutations required to convert
modern LLVM IR into something that more closely resembles LLVM-3.7 IR
so that the DXIL bitcode writer can emit 3.7 IR.

This change adds the codegen pass handling the first two IR
transformations:

* stripping new function attributes
* converting fneg into fsub

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D122081

Added: 
    llvm/lib/Target/DirectX/DXILPrepare.cpp
    llvm/lib/Target/DirectX/DirectX.h
    llvm/test/CodeGen/DirectX/fneg-conversion.ll
    llvm/test/CodeGen/DirectX/lit.local.cfg
    llvm/test/CodeGen/DirectX/strip-fn-attrs.ll

Modified: 
    llvm/lib/Target/DirectX/CMakeLists.txt
    llvm/lib/Target/DirectX/DirectXTargetMachine.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/DirectX/CMakeLists.txt b/llvm/lib/Target/DirectX/CMakeLists.txt
index a4ac6d212b5b8..240c7a518cfe2 100644
--- a/llvm/lib/Target/DirectX/CMakeLists.txt
+++ b/llvm/lib/Target/DirectX/CMakeLists.txt
@@ -9,6 +9,7 @@ add_public_tablegen_target(DirectXCommonTableGen)
 add_llvm_target(DirectXCodeGen
   DirectXSubtarget.cpp
   DirectXTargetMachine.cpp
+  DXILPrepare.cpp
 
   LINK_COMPONENTS
   Bitwriter

diff  --git a/llvm/lib/Target/DirectX/DXILPrepare.cpp b/llvm/lib/Target/DirectX/DXILPrepare.cpp
new file mode 100644
index 0000000000000..7f43051105cec
--- /dev/null
+++ b/llvm/lib/Target/DirectX/DXILPrepare.cpp
@@ -0,0 +1,126 @@
+//===- DXILPrepare.cpp - Prepare LLVM Module for DXIL encoding ------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file This file contains pases and utilities to convert a modern LLVM
+/// module into a module compatible with the LLVM 3.7-based DirectX Intermediate
+/// Language (DXIL).
+//===----------------------------------------------------------------------===//
+
+#include "DirectX.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Compiler.h"
+
+#define DEBUG_TYPE "dxil-prepare"
+
+using namespace llvm;
+
+namespace {
+
+constexpr bool isValidForDXIL(Attribute::AttrKind Attr) {
+  return is_contained({Attribute::Alignment,
+                       Attribute::AlwaysInline,
+                       Attribute::Builtin,
+                       Attribute::ByVal,
+                       Attribute::InAlloca,
+                       Attribute::Cold,
+                       Attribute::Convergent,
+                       Attribute::InlineHint,
+                       Attribute::InReg,
+                       Attribute::JumpTable,
+                       Attribute::MinSize,
+                       Attribute::Naked,
+                       Attribute::Nest,
+                       Attribute::NoAlias,
+                       Attribute::NoBuiltin,
+                       Attribute::NoCapture,
+                       Attribute::NoDuplicate,
+                       Attribute::NoImplicitFloat,
+                       Attribute::NoInline,
+                       Attribute::NonLazyBind,
+                       Attribute::NonNull,
+                       Attribute::Dereferenceable,
+                       Attribute::DereferenceableOrNull,
+                       Attribute::NoRedZone,
+                       Attribute::NoReturn,
+                       Attribute::NoUnwind,
+                       Attribute::OptimizeForSize,
+                       Attribute::OptimizeNone,
+                       Attribute::ReadNone,
+                       Attribute::ReadOnly,
+                       Attribute::ArgMemOnly,
+                       Attribute::Returned,
+                       Attribute::ReturnsTwice,
+                       Attribute::SExt,
+                       Attribute::StackAlignment,
+                       Attribute::StackProtect,
+                       Attribute::StackProtectReq,
+                       Attribute::StackProtectStrong,
+                       Attribute::SafeStack,
+                       Attribute::StructRet,
+                       Attribute::SanitizeAddress,
+                       Attribute::SanitizeThread,
+                       Attribute::SanitizeMemory,
+                       Attribute::UWTable,
+                       Attribute::ZExt},
+                      Attr);
+}
+
+class DXILPrepareModule : public ModulePass {
+public:
+  bool runOnModule(Module &M) override {
+    AttributeMask AttrMask;
+    for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds;
+         I = Attribute::AttrKind(I + 1)) {
+      if (!isValidForDXIL(I))
+        AttrMask.addAttribute(I);
+    }
+    for (auto &F : M.functions()) {
+      F.removeFnAttrs(AttrMask);
+      F.removeRetAttrs(AttrMask);
+      for (size_t Idx = 0; Idx < F.arg_size(); ++Idx)
+        F.removeParamAttrs(Idx, AttrMask);
+
+      for (auto &BB : F) {
+        IRBuilder<> Builder(&BB);
+        for (auto &I : make_early_inc_range(BB)) {
+          if (I.getOpcode() == Instruction::FNeg) {
+            Builder.SetInsertPoint(&I);
+            Value *In = I.getOperand(0);
+            Value *Zero = ConstantFP::get(In->getType(), -0.0);
+            I.replaceAllUsesWith(Builder.CreateFSub(Zero, In));
+            I.eraseFromParent();
+          }
+        }
+      }
+    }
+    return true;
+  }
+
+  DXILPrepareModule() : ModulePass(ID) {}
+
+  static char ID; // Pass identification.
+};
+char DXILPrepareModule::ID = 0;
+
+} // end anonymous namespace
+
+INITIALIZE_PASS_BEGIN(DXILPrepareModule, DEBUG_TYPE, "DXIL Prepare Module",
+                      false, false)
+INITIALIZE_PASS_END(DXILPrepareModule, DEBUG_TYPE, "DXIL Prepare Module", false,
+                    false)
+
+ModulePass *llvm::createDXILPrepareModulePass() {
+  return new DXILPrepareModule();
+}

diff  --git a/llvm/lib/Target/DirectX/DirectX.h b/llvm/lib/Target/DirectX/DirectX.h
new file mode 100644
index 0000000000000..4d5dc06a3aa24
--- /dev/null
+++ b/llvm/lib/Target/DirectX/DirectX.h
@@ -0,0 +1,25 @@
+//===- DirectXTargetMachine.h - DirectX Target Implementation ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_DIRECTX_DIRECTX_H
+#define LLVM_LIB_TARGET_DIRECTX_DIRECTX_H
+
+namespace llvm {
+class ModulePass;
+class PassRegistry;
+
+/// Initializer for DXIL-prepare
+void initializeDXILPrepareModulePass(PassRegistry &);
+
+/// Pass to convert modules into DXIL-compatable modules
+ModulePass *createDXILPrepareModulePass();
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_DIRECTX_DIRECTX_H

diff  --git a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
index 03572973bd770..4088dca20c226 100644
--- a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
+++ b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "DirectXTargetMachine.h"
+#include "DirectX.h"
 #include "DirectXSubtarget.h"
 #include "DirectXTargetTransformInfo.h"
 #include "TargetInfo/DirectXTargetInfo.h"
@@ -31,6 +32,8 @@ using namespace llvm;
 
 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() {
   RegisterTargetMachine<DirectXTargetMachine> X(getTheDirectXTarget());
+  auto *PR = PassRegistry::getPassRegistry();
+  initializeDXILPrepareModulePass(*PR);
 }
 
 class DXILTargetObjectFile : public TargetLoweringObjectFile {
@@ -81,6 +84,7 @@ bool DirectXTargetMachine::addPassesToEmitFile(
     PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
     CodeGenFileType FileType, bool DisableVerify,
     MachineModuleInfoWrapperPass *MMIWP) {
+  PM.add(createDXILPrepareModulePass());
   switch (FileType) {
   case CGFT_AssemblyFile:
     PM.add(createPrintModulePass(Out, "", true));

diff  --git a/llvm/test/CodeGen/DirectX/fneg-conversion.ll b/llvm/test/CodeGen/DirectX/fneg-conversion.ll
new file mode 100644
index 0000000000000..2947e738807a2
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/fneg-conversion.ll
@@ -0,0 +1,14 @@
+; RUN: llc %s --filetype=asm -o - | FileCheck %s
+target triple = "dxil-unknown-unknown"
+
+define float @negateF(float %0) {
+; CHECK:  %2 = fsub float -0.000000e+00, %0
+  %2 = fneg float %0
+  ret float %2
+}
+
+define double @negateD(double %0) {
+; CHECK: %2 = fsub double -0.000000e+00, %0
+  %2 = fneg double %0
+  ret double %2
+}

diff  --git a/llvm/test/CodeGen/DirectX/lit.local.cfg b/llvm/test/CodeGen/DirectX/lit.local.cfg
new file mode 100644
index 0000000000000..95c31776c9a5d
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/lit.local.cfg
@@ -0,0 +1,2 @@
+if not 'DirectX' in config.root.targets:
+  config.unsupported = True

diff  --git a/llvm/test/CodeGen/DirectX/strip-fn-attrs.ll b/llvm/test/CodeGen/DirectX/strip-fn-attrs.ll
new file mode 100644
index 0000000000000..53eb5e2507912
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/strip-fn-attrs.ll
@@ -0,0 +1,20 @@
+; RUN: llc %s --filetype=asm -o - | FileCheck %s
+target triple = "dxil-unknown-unknown"
+
+; CHECK: Function Attrs: nounwind readnone
+; Function Attrs: norecurse nounwind readnone willreturn
+define dso_local float @fma(float %0, float %1, float %2) local_unnamed_addr #0 {
+  %4 = fmul float %0, %1
+  %5 = fadd float %4, %2
+  ret float %5
+}
+
+; CHECK: Function Attrs: nounwind readnone
+; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
+declare void @llvm.dbg.value(metadata, metadata, metadata) #1
+
+; CHECK: attributes #0 = { nounwind readnone }
+; CHECK-NOT attributes #
+
+attributes #0 = { norecurse nounwind readnone willreturn }
+attributes #1 = { nofree nosync nounwind readnone speculatable willreturn }


        


More information about the llvm-commits mailing list