Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HEXAGON] Utilize new mask instruction #92365

Merged
merged 3 commits into from
Aug 5, 2024

Conversation

quic-asaravan
Copy link
Contributor

This pass utilizes the new Hexagon Mask Instruction.
Authored by : Harsha Jagasia, Krzysztof Parzyszek

@quic-asaravan
Copy link
Contributor Author

@iajbar @SundeepKushwaha Can you please review this?

@xgupta
Copy link
Contributor

xgupta commented May 17, 2024

It does LGTM but someone more qualified should accept the PR.

@quic-asaravan
Copy link
Contributor Author

@kparzysz Can you please review this? Thank you.

@xgupta
Copy link
Contributor

xgupta commented Jun 15, 2024

@pgodeq might know about Qualcomm Hexagon and can accept this PR.

@pgodeq
Copy link

pgodeq commented Jun 17, 2024

@pgodeq might know about Qualcomm Hexagon and can accept this PR.

Let me check with folks.

@iajbar
Copy link
Contributor

iajbar commented Jun 28, 2024

LGTM.

@iajbar iajbar self-assigned this Jun 28, 2024

#if defined(_MSC_VER)
#include <intrin.h>
#endif
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need intrin.h here?

HII = HST.getInstrInfo();
const Function &F = MF.getFunction();

if (!F.hasFnAttribute(Attribute::OptimizeForSize))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment explaining the reasoning behind this heuristic might be helpful.

@androm3da
Copy link
Member

I have removed some unrelated reviewers caused by unintentional commits added (then removed) recently.

@llvmbot
Copy link
Collaborator

llvmbot commented Jul 12, 2024

@llvm/pr-subscribers-backend-hexagon

Author: Abinaya Saravanan (quic-asaravan)

Changes

This pass utilizes the new Hexagon Mask Instruction.
Authored by : Harsha Jagasia, Krzysztof Parzyszek


Full diff: https://github.com/llvm/llvm-project/pull/92365.diff

4 Files Affected:

  • (modified) llvm/lib/Target/Hexagon/CMakeLists.txt (+1)
  • (added) llvm/lib/Target/Hexagon/HexagonMask.cpp (+111)
  • (modified) llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp (+11)
  • (added) llvm/test/CodeGen/Hexagon/mask.ll (+17)
diff --git a/llvm/lib/Target/Hexagon/CMakeLists.txt b/llvm/lib/Target/Hexagon/CMakeLists.txt
index 9e4ca08aea40d..e8ec93dd5ee63 100644
--- a/llvm/lib/Target/Hexagon/CMakeLists.txt
+++ b/llvm/lib/Target/Hexagon/CMakeLists.txt
@@ -48,6 +48,7 @@ add_llvm_target(HexagonCodeGen
   HexagonLoopIdiomRecognition.cpp
   HexagonMachineFunctionInfo.cpp
   HexagonMachineScheduler.cpp
+  HexagonMask.cpp
   HexagonMCInstLower.cpp
   HexagonNewValueJump.cpp
   HexagonOptAddrMode.cpp
diff --git a/llvm/lib/Target/Hexagon/HexagonMask.cpp b/llvm/lib/Target/Hexagon/HexagonMask.cpp
new file mode 100644
index 0000000000000..e9ed237a4f115
--- /dev/null
+++ b/llvm/lib/Target/Hexagon/HexagonMask.cpp
@@ -0,0 +1,111 @@
+//===-- HexagonMask.cpp - replace const ext tfri with mask ------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "mask"
+
+#include "HexagonMachineFunctionInfo.h"
+#include "HexagonSubtarget.h"
+#include "HexagonTargetMachine.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Target/TargetMachine.h"
+
+#if defined(_MSC_VER)
+#include <intrin.h>
+#endif
+
+using namespace llvm;
+
+namespace llvm {
+FunctionPass *createHexagonMask();
+void initializeHexagonMaskPass(PassRegistry &);
+
+class HexagonMask : public MachineFunctionPass {
+public:
+  static char ID;
+  HexagonMask() : MachineFunctionPass(ID) {
+    PassRegistry &Registry = *PassRegistry::getPassRegistry();
+    initializeHexagonMaskPass(Registry);
+  }
+
+  StringRef getPassName() const override {
+    return "Hexagon replace const ext tfri with mask";
+  }
+  bool runOnMachineFunction(MachineFunction &MF) override;
+
+private:
+  const HexagonInstrInfo *HII;
+  void replaceConstExtTransferImmWithMask(MachineFunction &MF);
+};
+
+char HexagonMask::ID = 0;
+
+void HexagonMask::replaceConstExtTransferImmWithMask(MachineFunction &MF) {
+  for (auto &MBB : MF) {
+    for (auto &MI : llvm::make_early_inc_range(MBB)) {
+      if (MI.getOpcode() != Hexagon::A2_tfrsi)
+        continue;
+
+      const MachineOperand &Op0 = MI.getOperand(0);
+      const MachineOperand &Op1 = MI.getOperand(1);
+      if (!Op1.isImm())
+        continue;
+      int32_t V = Op1.getImm();
+      if (isInt<16>(V))
+        continue;
+
+      unsigned Idx, Len;
+      if (!isShiftedMask_32(V, Idx, Len))
+        continue;
+      if (!isUInt<5>(Idx) || !isUInt<5>(Len))
+        continue;
+
+      BuildMI(MBB, MI, MI.getDebugLoc(), HII->get(Hexagon::S2_mask),
+              Op0.getReg())
+          .addImm(Len)
+          .addImm(Idx);
+      MBB.erase(MI);
+    }
+  }
+}
+
+bool HexagonMask::runOnMachineFunction(MachineFunction &MF) {
+  auto &HST = MF.getSubtarget<HexagonSubtarget>();
+  HII = HST.getInstrInfo();
+  const Function &F = MF.getFunction();
+
+  if (!F.hasFnAttribute(Attribute::OptimizeForSize))
+    return false;
+
+  replaceConstExtTransferImmWithMask(MF);
+
+  return true;
+}
+
+} // namespace llvm
+
+//===----------------------------------------------------------------------===//
+//                         Public Constructor Functions
+//===----------------------------------------------------------------------===//
+
+INITIALIZE_PASS(HexagonMask, "hexagon-mask", "Hexagon mask", false, false)
+
+FunctionPass *llvm::createHexagonMask() { return new HexagonMask(); }
diff --git a/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp b/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
index b362285d4f16e..803b9b81045c6 100644
--- a/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
@@ -59,6 +59,10 @@ static cl::opt<bool>
     DisableHCP("disable-hcp", cl::Hidden,
                cl::desc("Disable Hexagon constant propagation"));
 
+static cl::opt<bool> DisableHexagonMask(
+    "disable-mask", cl::Hidden,
+    cl::desc("Disable Hexagon specific Mask generation pass"));
+
 static cl::opt<bool> DisableStoreWidening("disable-store-widen", cl::Hidden,
                                           cl::init(false),
                                           cl::desc("Disable store widening"));
@@ -180,6 +184,8 @@ void initializeHexagonGenMuxPass(PassRegistry &);
 void initializeHexagonHardwareLoopsPass(PassRegistry &);
 void initializeHexagonLoopIdiomRecognizeLegacyPassPass(PassRegistry &);
 void initializeHexagonLoopAlignPass(PassRegistry &);
+void initializeHexagonMaskPass(PassRegistry &);
+void initializeHexagonMergeActivateWeightPass(PassRegistry &);
 void initializeHexagonNewValueJumpPass(PassRegistry &);
 void initializeHexagonOptAddrModePass(PassRegistry &);
 void initializeHexagonPacketizerPass(PassRegistry &);
@@ -213,6 +219,8 @@ FunctionPass *createHexagonISelDag(HexagonTargetMachine &TM,
                                    CodeGenOptLevel OptLevel);
 FunctionPass *createHexagonLoopAlign();
 FunctionPass *createHexagonLoopRescheduling();
+FunctionPass *createHexagonMask();
+FunctionPass *createHexagonMergeActivateWeight();
 FunctionPass *createHexagonNewValueJump();
 FunctionPass *createHexagonOptAddrMode();
 FunctionPass *createHexagonOptimizeSZextends();
@@ -474,10 +482,13 @@ void HexagonPassConfig::addPostRegAlloc() {
 }
 
 void HexagonPassConfig::addPreSched2() {
+  bool NoOpt = (getOptLevel() == CodeGenOptLevel::None);
   addPass(createHexagonCopyToCombine());
   if (getOptLevel() != CodeGenOptLevel::None)
     addPass(&IfConverterID);
   addPass(createHexagonSplitConst32AndConst64());
+  if (!NoOpt && !DisableHexagonMask)
+    addPass(createHexagonMask());
 }
 
 void HexagonPassConfig::addPreEmitPass() {
diff --git a/llvm/test/CodeGen/Hexagon/mask.ll b/llvm/test/CodeGen/Hexagon/mask.ll
new file mode 100644
index 0000000000000..698d1ac26d248
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/mask.ll
@@ -0,0 +1,17 @@
+; RUN: llc -mtriple=hexagon -mcpu=hexagonv73 < %s | FileCheck %s
+
+target triple = "hexagon"
+
+; CHECK-LABEL: test1:
+; CHECK: r0 = mask(#25,#2)
+; Function Attrs: optsize
+define i32 @test1() #1 {
+entry:
+  %0 = call i32 @llvm.hexagon.A2.tfr(i32 134217724)
+  ret i32 %0
+}
+
+declare i32 @llvm.hexagon.A2.tfr(i32) #0
+
+attributes #0 = { nounwind readnone }
+attributes #1 = { optsize }

Copy link

github-actions bot commented Jul 29, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff a8e1c3e1239604ac787b6a2d39b5278ddec8aa8a fed67f7151518d35afcacd7a3da61ff2701fcc05 --extensions cpp -- llvm/lib/Target/Hexagon/HexagonMask.cpp llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
View the diff from clang-format here.
diff --git a/llvm/lib/Target/Hexagon/HexagonMask.cpp b/llvm/lib/Target/Hexagon/HexagonMask.cpp
index 6a06efd307..ac9abfa6c1 100644
--- a/llvm/lib/Target/Hexagon/HexagonMask.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonMask.cpp
@@ -90,9 +90,10 @@ bool HexagonMask::runOnMachineFunction(MachineFunction &MF) {
 
   if (!F.hasFnAttribute(Attribute::OptimizeForSize))
     return false;
-  // The mask instruction available in v66 can be used to generate values in registers using 2 immediates
-  // Eg. to form 0x07fffffc in R0, you would write "R0 = mask(#25,#2)"
-  // Since it is a single-word instruction, it takes less code size than a constant-extended transfer at Os
+  // The mask instruction available in v66 can be used to generate values in
+  // registers using 2 immediates Eg. to form 0x07fffffc in R0, you would write
+  // "R0 = mask(#25,#2)" Since it is a single-word instruction, it takes less
+  // code size than a constant-extended transfer at Os
   replaceConstExtTransferImmWithMask(MF);
 
   return true;

Co-authored-by: Harsha Jagasia <[email protected]>
Co-authored-by: Krzysztof Parzyszek <[email protected]>
@quic-asaravan quic-asaravan merged commit c04857c into llvm:main Aug 5, 2024
7 checks passed
banach-space pushed a commit to banach-space/llvm-project that referenced this pull request Aug 7, 2024
This pass utilizes the new Hexagon Mask Instruction.
Authored by : Harsha Jagasia, Krzysztof Parzyszek

Co-authored-by: Harsha Jagasia <[email protected]>
Co-authored-by: Krzysztof Parzyszek <[email protected]>
@nathanchance
Copy link
Member

I notice a backend error when building the Linux kernel for ARCH=hexagon after this change.

int atmel_console_get_options_mr;
_Bool atmel_console_setup_atmel_port_3;
void __attribute__((__cold__)) atmel_console_setup() {
  int flow = atmel_console_setup_atmel_port_3, __trans_tmp_12, quot,
      __trans_tmp_5, val;
  asm("" : "=&r"(val));
  __trans_tmp_5 = val;
  __trans_tmp_12 = __trans_tmp_5;
  quot = __trans_tmp_12 & ~0UL >> 5;
  if (quot)
    atmel_console_get_options_mr = flow;
}
$ clang --target=hexagon -c -o /dev/null atmel_serial.i

$ clang --target=hexagon -c -o /dev/null atmel_serial.i -O2
fatal error: error in backend: Attempting to emit S2_mask instruction but the Feature_HasV66 predicate(s) are not met
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.	Program arguments: clang --target=hexagon -c -o /dev/null atmel_serial.i -O2
1.	<eof> parser at end of file
2.	Code generation
3.	Running pass 'Function Pass Manager' on module 'atmel_serial.i'.
4.	Running pass 'Hexagon Assembly Printer' on function '@atmel_console_setup'
 #0 0x00005598a69c8496 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x5650496)
 #1 0x00005598a69c5f5e llvm::sys::RunSignalHandlers() (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x564df5e)
 #2 0x00005598a6947ec7 (anonymous namespace)::CrashRecoveryContextImpl::HandleCrash(int, unsigned long) CrashRecoveryContext.cpp:0:0
 #3 0x00005598a6947e5f llvm::CrashRecoveryContext::HandleExit(int) (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x55cfe5f)
 #4 0x00005598a69c27f7 llvm::sys::Process::Exit(int, bool) (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x564a7f7)
 #5 0x00005598a4a1c7c3 (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x36a47c3)
 #6 0x00005598a694e339 llvm::report_fatal_error(llvm::Twine const&, bool) (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x55d6339)
 #7 0x00005598a694e226 (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x55d6226)
 #8 0x00005598a5228fc3 llvm::Hexagon_MC::verifyInstructionPredicates(unsigned int, llvm::FeatureBitset const&) HexagonMCTargetDesc.cpp:0:0
 #9 0x00005598a505fbcf llvm::HexagonAsmPrinter::emitInstruction(llvm::MachineInstr const*) HexagonAsmPrinter.cpp:0:0
#10 0x00005598a7a5a4f0 llvm::AsmPrinter::emitFunctionBody() (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x66e24f0)
#11 0x00005598a5060160 llvm::HexagonAsmPrinter::runOnMachineFunction(llvm::MachineFunction&) HexagonAsmPrinter.cpp:0:0
#12 0x00005598a5f3caf2 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x4bc4af2)
#13 0x00005598a64c02c8 llvm::FPPassManager::runOnFunction(llvm::Function&) (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x51482c8)
#14 0x00005598a64c8c82 llvm::FPPassManager::runOnModule(llvm::Module&) (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x5150c82)
#15 0x00005598a64c0df2 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x5148df2)
#16 0x00005598a7207dd0 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>, clang::BackendConsumer*) (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x5e8fdd0)
#17 0x00005598a722f007 clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x5eb7007)
#18 0x00005598a86bfe99 clang::ParseAST(clang::Sema&, bool, bool) (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x7347e99)
#19 0x00005598a76c5c0d clang::FrontendAction::Execute() (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x634dc0d)
#20 0x00005598a7629cad clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x62b1cad)
#21 0x00005598a77a262c clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x642a62c)
#22 0x00005598a4a1c395 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x36a4395)
#23 0x00005598a4a189dd ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#24 0x00005598a744e269 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::$_0>(long) Job.cpp:0:0
#25 0x00005598a6947df6 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x55cfdf6)
#26 0x00005598a744d903 clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x60d5903)
#27 0x00005598a7405537 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x608d537)
#28 0x00005598a7405a97 clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x608da97)
#29 0x00005598a74281c9 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x60b01c9)
#30 0x00005598a4a17e7d clang_main(int, char**, llvm::ToolContext const&) (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x369fe7d)
#31 0x00005598a4a29806 main (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x36b1806)
#32 0x00007f423fa0be08 (/usr/lib/libc.so.6+0x25e08)
#33 0x00007f423fa0becc __libc_start_main (/usr/lib/libc.so.6+0x25ecc)
#34 0x00005598a4a162a5 _start (/home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin/clang-20+0x369e2a5)
clang: error: clang frontend command failed with exit code 70 (use -v to see invocation)
ClangBuiltLinux clang version 20.0.0git (https://github.com/llvm/llvm-project.git c04857cb2c9f6f2e8add61192c62e48a83938efd)
Target: hexagon
Thread model: posix
InstalledDir: /home/nathan/tmp/cvise.oHgX5B9Sms/install/llvm-bad/bin
Build config: +assertions
clang: note: diagnostic msg: Error generating preprocessed source(s) - no preprocessable inputs.

@androm3da
Copy link
Member

So @quic-asaravan given this new failure maybe we should revert this change?

@quic-asaravan
Copy link
Contributor Author

I have a fix for this issue. I will merge it shortly.

@quic-asaravan
Copy link
Contributor Author

#102880 - fix merged @nathanchance Can you pls verify whether the issue is resolved ?

@nathanchance
Copy link
Member

@quic-asaravan Yes, I can confirm that patch resolves my reported issue.

kstoimenov pushed a commit to kstoimenov/llvm-project that referenced this pull request Aug 15, 2024
This pass utilizes the new Hexagon Mask Instruction.
Authored by : Harsha Jagasia, Krzysztof Parzyszek

Co-authored-by: Harsha Jagasia <[email protected]>
Co-authored-by: Krzysztof Parzyszek <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants