//===-- AMDGPULowerIntrinsics.cpp -------------------------------------------=//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Lower intrinsics that would otherwise require separate handling in both
// SelectionDAG and GlobalISel.
//
//===----------------------------------------------------------------------===//

#include "AMDGPU.h"
#include "AMDGPUTargetMachine.h"
#include "GCNSubtarget.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/IntrinsicsAMDGPU.h"
#include "llvm/InitializePasses.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"

#define DEBUG_TYPE "amdgpu-lower-intrinsics"

using namespace llvm;

namespace {

class AMDGPULowerIntrinsicsImpl {
public:
  Module &M;
  const AMDGPUTargetMachine &TM;

  AMDGPULowerIntrinsicsImpl(Module &M, const AMDGPUTargetMachine &TM)
      : M(M), TM(TM) {}

  bool run();

private:
  bool visitBarrier(IntrinsicInst &I);
  bool visitPtrSBufferLoad(IntrinsicInst &I);
  bool visitMonitorSleep(IntrinsicInst &I);
  bool visitCvtScale(IntrinsicInst &I);
};

class AMDGPULowerIntrinsicsLegacy : public ModulePass {
public:
  static char ID;

  AMDGPULowerIntrinsicsLegacy() : ModulePass(ID) {}

  bool runOnModule(Module &M) override;

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.addRequired<TargetPassConfig>();
  }
};

template <class T> static void forEachCall(Function &Intrin, T Callback) {
  for (User *U : make_early_inc_range(Intrin.users())) {
    if (auto *CI = dyn_cast<IntrinsicInst>(U))
      Callback(CI);
  }
}

} // anonymous namespace

bool AMDGPULowerIntrinsicsImpl::run() {
  bool Changed = false;

  for (Function &F : M) {
    switch (F.getIntrinsicID()) {
    default:
      continue;
    case Intrinsic::amdgcn_s_barrier:
    case Intrinsic::amdgcn_s_barrier_signal:
    case Intrinsic::amdgcn_s_barrier_signal_isfirst:
    case Intrinsic::amdgcn_s_barrier_wait:
    case Intrinsic::amdgcn_s_cluster_barrier:
      forEachCall(F, [&](IntrinsicInst *II) { Changed |= visitBarrier(*II); });
      break;
    case Intrinsic::amdgcn_ptr_s_buffer_load:
      forEachCall(
          F, [&](IntrinsicInst *II) { Changed |= visitPtrSBufferLoad(*II); });
      break;
    case Intrinsic::amdgcn_s_monitor_sleep:
      forEachCall(
          F, [&](IntrinsicInst *II) { Changed |= visitMonitorSleep(*II); });
      break;
    case Intrinsic::amdgcn_cvt_scale_pk8_f16_fp8:
    case Intrinsic::amdgcn_cvt_scale_pk8_bf16_fp8:
    case Intrinsic::amdgcn_cvt_scale_pk8_f16_bf8:
    case Intrinsic::amdgcn_cvt_scale_pk8_bf16_bf8:
    case Intrinsic::amdgcn_cvt_scale_pk8_f16_fp4:
    case Intrinsic::amdgcn_cvt_scale_pk8_bf16_fp4:
    case Intrinsic::amdgcn_cvt_scale_pk8_f32_fp8:
    case Intrinsic::amdgcn_cvt_scale_pk8_f32_bf8:
    case Intrinsic::amdgcn_cvt_scale_pk8_f32_fp4:
    case Intrinsic::amdgcn_cvt_scale_pk16_f16_bf6:
    case Intrinsic::amdgcn_cvt_scale_pk16_bf16_bf6:
    case Intrinsic::amdgcn_cvt_scale_pk16_f16_fp6:
    case Intrinsic::amdgcn_cvt_scale_pk16_bf16_fp6:
    case Intrinsic::amdgcn_cvt_scale_pk16_f32_fp6:
    case Intrinsic::amdgcn_cvt_scale_pk16_f32_bf6:
      forEachCall(F, [&](IntrinsicInst *II) { Changed |= visitCvtScale(*II); });
      break;
    }
  }

  return Changed;
}

// Optimize barriers and lower s_(cluster_)barrier to a sequence of split
// barrier intrinsics.
bool AMDGPULowerIntrinsicsImpl::visitBarrier(IntrinsicInst &I) {
  assert(I.getIntrinsicID() == Intrinsic::amdgcn_s_barrier ||
         I.getIntrinsicID() == Intrinsic::amdgcn_s_barrier_signal ||
         I.getIntrinsicID() == Intrinsic::amdgcn_s_barrier_signal_isfirst ||
         I.getIntrinsicID() == Intrinsic::amdgcn_s_barrier_wait ||
         I.getIntrinsicID() == Intrinsic::amdgcn_s_cluster_barrier);

  const GCNSubtarget &ST = TM.getSubtarget<GCNSubtarget>(*I.getFunction());
  bool IsSingleWaveWG = false;

  if (TM.getOptLevel() > CodeGenOptLevel::None) {
    unsigned WGMaxSize = ST.getFlatWorkGroupSizes(*I.getFunction()).second;
    IsSingleWaveWG = WGMaxSize <= ST.getWavefrontSize();
  }

  IRBuilder<> B(&I);

  // Lower the s_cluster_barrier intrinsic first. There is no corresponding
  // hardware instruction in any subtarget.
  if (I.getIntrinsicID() == Intrinsic::amdgcn_s_cluster_barrier) {
    // The default cluster barrier expects one signal per workgroup. So we need
    // a workgroup barrier first.
    if (IsSingleWaveWG) {
      B.CreateIntrinsicWithoutFolding(B.getVoidTy(),
                                      Intrinsic::amdgcn_wave_barrier, {})
          ->copyMetadata(I);
    } else {
      Value *BarrierID_32 = B.getInt32(AMDGPU::Barrier::WORKGROUP);
      Value *BarrierID_16 = B.getInt16(AMDGPU::Barrier::WORKGROUP);
      CallInst *IsFirst = B.CreateIntrinsicWithoutFolding(
          B.getInt1Ty(), Intrinsic::amdgcn_s_barrier_signal_isfirst,
          {BarrierID_32});
      IsFirst->copyMetadata(I);
      B.CreateIntrinsicWithoutFolding(
           B.getVoidTy(), Intrinsic::amdgcn_s_barrier_wait, {BarrierID_16})
          ->copyMetadata(I);

      Instruction *ThenTerm =
          SplitBlockAndInsertIfThen(IsFirst, I.getIterator(), false);
      B.SetInsertPoint(ThenTerm);
    }

    // Now we can signal the cluster barrier from a single wave and wait for the
    // barrier in all waves.
    Value *BarrierID_32 = B.getInt32(AMDGPU::Barrier::CLUSTER);
    Value *BarrierID_16 = B.getInt16(AMDGPU::Barrier::CLUSTER);
    B.CreateIntrinsicWithoutFolding(
         B.getVoidTy(), Intrinsic::amdgcn_s_barrier_signal, {BarrierID_32})
        ->copyMetadata(I);

    B.SetInsertPoint(&I);
    B.CreateIntrinsicWithoutFolding(
         B.getVoidTy(), Intrinsic::amdgcn_s_barrier_wait, {BarrierID_16})
        ->copyMetadata(I);

    I.eraseFromParent();
    return true;
  }

  bool IsWorkgroupScope = false;

  if (I.getIntrinsicID() == Intrinsic::amdgcn_s_barrier_wait ||
      I.getIntrinsicID() == Intrinsic::amdgcn_s_barrier_signal ||
      I.getIntrinsicID() == Intrinsic::amdgcn_s_barrier_signal_isfirst) {
    int BarrierID = cast<ConstantInt>(I.getArgOperand(0))->getSExtValue();
    if (BarrierID == AMDGPU::Barrier::TRAP ||
        BarrierID == AMDGPU::Barrier::WORKGROUP ||
        (BarrierID >= AMDGPU::Barrier::NAMED_BARRIER_FIRST &&
         BarrierID <= AMDGPU::Barrier::NAMED_BARRIER_LAST))
      IsWorkgroupScope = true;
    else if (I.getIntrinsicID() == Intrinsic::amdgcn_s_barrier_signal_isfirst &&
             BarrierID == AMDGPU::Barrier::CLUSTER) {
      I.getContext().diagnose(
          DiagnosticInfoUnsupported(*I.getFunction(),
                                    "s_barrier_signal_isfirst does not support "
                                    "user_cluster_barrier_id (-3)",
                                    I.getDebugLoc()));
    }
  } else {
    assert(I.getIntrinsicID() == Intrinsic::amdgcn_s_barrier);
    IsWorkgroupScope = true;
  }

  if (IsWorkgroupScope && IsSingleWaveWG) {
    // Down-grade waits, remove split signals.
    if (I.getIntrinsicID() == Intrinsic::amdgcn_s_barrier ||
        I.getIntrinsicID() == Intrinsic::amdgcn_s_barrier_wait) {
      B.CreateIntrinsicWithoutFolding(B.getVoidTy(),
                                      Intrinsic::amdgcn_wave_barrier, {})
          ->copyMetadata(I);
    } else if (I.getIntrinsicID() ==
               Intrinsic::amdgcn_s_barrier_signal_isfirst) {
      // If we're the only wave of the workgroup, we're always first.
      I.replaceAllUsesWith(B.getInt1(true));
    }
    I.eraseFromParent();
    return true;
  }

  if (I.getIntrinsicID() == Intrinsic::amdgcn_s_barrier &&
      ST.hasSplitBarriers()) {
    // Lower to split barriers.
    Value *BarrierID_32 = B.getInt32(AMDGPU::Barrier::WORKGROUP);
    Value *BarrierID_16 = B.getInt16(AMDGPU::Barrier::WORKGROUP);
    B.CreateIntrinsicWithoutFolding(
         B.getVoidTy(), Intrinsic::amdgcn_s_barrier_signal, {BarrierID_32})
        ->copyMetadata(I);
    B.CreateIntrinsicWithoutFolding(
         B.getVoidTy(), Intrinsic::amdgcn_s_barrier_wait, {BarrierID_16})
        ->copyMetadata(I);
    I.eraseFromParent();
    return true;
  }

  return false;
}

bool AMDGPULowerIntrinsicsImpl::visitPtrSBufferLoad(IntrinsicInst &I) {
  assert(I.getIntrinsicID() == Intrinsic::amdgcn_ptr_s_buffer_load);

  if (I.hasMetadata(LLVMContext::MD_invariant_load))
    return false;

  I.setMetadata(LLVMContext::MD_invariant_load,
                MDNode::get(I.getContext(), {}));
  return true;
}

bool AMDGPULowerIntrinsicsImpl::visitMonitorSleep(IntrinsicInst &I) {
  assert(I.getIntrinsicID() == Intrinsic::amdgcn_s_monitor_sleep);

  const GCNSubtarget &ST = TM.getSubtarget<GCNSubtarget>(*I.getFunction());
  if (!ST.hasNoSleepForever())
    return false;

  int Sleep = cast<ConstantInt>(I.getArgOperand(0))->getSExtValue();
  if (!(Sleep & 0x8000))
    return false;

  IRBuilder<> B(&I);
  Value *NewSleep = B.getInt16(0x2000); // Maximum
  I.setArgOperand(0, NewSleep);

  return true;
}

bool AMDGPULowerIntrinsicsImpl::visitCvtScale(IntrinsicInst &I) {
  int MaxSel = 0;
  switch (I.getIntrinsicID()) {
  default:
    llvm_unreachable("expected cvt_scale_* intrinsic");
  case Intrinsic::amdgcn_cvt_scale_pk8_f16_fp8:
  case Intrinsic::amdgcn_cvt_scale_pk8_bf16_fp8:
  case Intrinsic::amdgcn_cvt_scale_pk8_f16_bf8:
  case Intrinsic::amdgcn_cvt_scale_pk8_bf16_bf8:
  case Intrinsic::amdgcn_cvt_scale_pk8_f32_fp8:
  case Intrinsic::amdgcn_cvt_scale_pk8_f32_bf8:
    MaxSel = 8;
    break;
  case Intrinsic::amdgcn_cvt_scale_pk8_f16_fp4:
  case Intrinsic::amdgcn_cvt_scale_pk8_bf16_fp4:
  case Intrinsic::amdgcn_cvt_scale_pk8_f32_fp4:
  case Intrinsic::amdgcn_cvt_scale_pk16_f16_bf6:
  case Intrinsic::amdgcn_cvt_scale_pk16_bf16_bf6:
  case Intrinsic::amdgcn_cvt_scale_pk16_f16_fp6:
  case Intrinsic::amdgcn_cvt_scale_pk16_bf16_fp6:
  case Intrinsic::amdgcn_cvt_scale_pk16_f32_fp6:
  case Intrinsic::amdgcn_cvt_scale_pk16_f32_bf6:
    MaxSel = 4;
    break;
  }

  const GCNSubtarget &ST = TM.getSubtarget<GCNSubtarget>(*I.getFunction());
  if (ST.hasBlock16ConversionScaleInsts())
    MaxSel *= 2;

  int ScaleSel = cast<ConstantInt>(I.getArgOperand(2))->getSExtValue();
  if (ScaleSel < MaxSel)
    return false;

  I.getContext().diagnose(DiagnosticInfoUnsupported(
      *I.getFunction(),
      I.getCalledFunction()->getName() +
          Twine(" scale_sel maximum supported value is ") + Twine(MaxSel - 1),
      I.getDebugLoc()));

  return false;
}

PreservedAnalyses AMDGPULowerIntrinsicsPass::run(Module &M,
                                                 ModuleAnalysisManager &MAM) {
  AMDGPULowerIntrinsicsImpl Impl(M, TM);
  if (!Impl.run())
    return PreservedAnalyses::all();
  return PreservedAnalyses::none();
}

bool AMDGPULowerIntrinsicsLegacy::runOnModule(Module &M) {
  auto &TPC = getAnalysis<TargetPassConfig>();
  const AMDGPUTargetMachine &TM = TPC.getTM<AMDGPUTargetMachine>();

  AMDGPULowerIntrinsicsImpl Impl(M, TM);
  return Impl.run();
}

#define PASS_DESC "AMDGPU lower intrinsics"
INITIALIZE_PASS_BEGIN(AMDGPULowerIntrinsicsLegacy, DEBUG_TYPE, PASS_DESC, false,
                      false)
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
INITIALIZE_PASS_END(AMDGPULowerIntrinsicsLegacy, DEBUG_TYPE, PASS_DESC, false,
                    false)

char AMDGPULowerIntrinsicsLegacy::ID = 0;

ModulePass *llvm::createAMDGPULowerIntrinsicsLegacyPass() {
  return new AMDGPULowerIntrinsicsLegacy;
}
