Skip to content

Commit cc934b3

Browse files
committed
Move isspacep intrinsics processing to NVPTX backend
1 parent fffb81e commit cc934b3

File tree

2 files changed

+60
-29
lines changed

2 files changed

+60
-29
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6367,32 +6367,6 @@ static Value *simplifyUnaryIntrinsic(Function *F, Value *Op0,
63676367

63686368
break;
63696369
}
6370-
case Intrinsic::nvvm_isspacep_global:
6371-
case Intrinsic::nvvm_isspacep_local:
6372-
case Intrinsic::nvvm_isspacep_shared:
6373-
case Intrinsic::nvvm_isspacep_const: {
6374-
auto *Ty = F->getReturnType();
6375-
unsigned AS = Op0->getType()->getPointerAddressSpace();
6376-
if (AS == NVPTXAS::ADDRESS_SPACE_GENERIC) {
6377-
if (auto *ASC = dyn_cast<AddrSpaceCastInst>(Op0))
6378-
AS = ASC->getSrcAddressSpace();
6379-
else if (auto *ASCO = dyn_cast<AddrSpaceCastOperator>(Op0))
6380-
AS = ASCO->getOperand(0)->getType()->getPointerAddressSpace();
6381-
}
6382-
if (AS == NVPTXAS::ADDRESS_SPACE_GENERIC ||
6383-
AS == NVPTXAS::ADDRESS_SPACE_PARAM)
6384-
return nullptr; // Got to check at run-time.
6385-
bool ASMatches = (AS == NVPTXAS::ADDRESS_SPACE_GLOBAL &&
6386-
IID == Intrinsic::nvvm_isspacep_global) ||
6387-
(AS == NVPTXAS::ADDRESS_SPACE_LOCAL &&
6388-
IID == Intrinsic::nvvm_isspacep_local) ||
6389-
(AS == NVPTXAS::ADDRESS_SPACE_SHARED &&
6390-
IID == Intrinsic::nvvm_isspacep_shared) ||
6391-
(AS == NVPTXAS::ADDRESS_SPACE_CONST &&
6392-
IID == Intrinsic::nvvm_isspacep_const);
6393-
return ConstantInt::get(Ty, ASMatches);
6394-
break;
6395-
}
63966370
default:
63976371
break;
63986372
}

llvm/lib/Target/NVPTX/NVPTXTargetTransformInfo.cpp

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
1515
#include "llvm/CodeGen/CostTable.h"
1616
#include "llvm/CodeGen/TargetLowering.h"
1717
#include "llvm/IR/Constants.h"
18+
#include "llvm/IR/IntrinsicInst.h"
1819
#include "llvm/IR/Intrinsics.h"
1920
#include "llvm/IR/IntrinsicsNVPTX.h"
2021
#include "llvm/IR/Value.h"
2122
#include "llvm/Support/Casting.h"
23+
#include "llvm/Support/ErrorHandling.h"
2224
#include "llvm/Transforms/InstCombine/InstCombiner.h"
2325
#include <optional>
2426
using namespace llvm;
@@ -117,7 +119,8 @@ bool NVPTXTTIImpl::isSourceOfDivergence(const Value *V) {
117119
}
118120

119121
// Convert NVVM intrinsics to target-generic LLVM code where possible.
120-
static Instruction *simplifyNvvmIntrinsic(IntrinsicInst *II, InstCombiner &IC) {
122+
static Instruction *convertNvvmIntrinsicToLlvm(InstCombiner &IC,
123+
IntrinsicInst *II) {
121124
// Each NVVM intrinsic we can simplify can be replaced with one of:
122125
//
123126
// * an LLVM intrinsic,
@@ -413,11 +416,65 @@ static Instruction *simplifyNvvmIntrinsic(IntrinsicInst *II, InstCombiner &IC) {
413416
llvm_unreachable("All SpecialCase enumerators should be handled in switch.");
414417
}
415418

419+
// Returns an instruction pointer (may be nullptr if we do not know the answer).
420+
// Returns nullopt if `II` is not one of the `isspacep` intrinsics.
421+
static std::optional<Instruction *>
422+
handleSpaceCheckIntrinsics(InstCombiner &IC, IntrinsicInst &II) {
423+
Value *Op0 = II.getArgOperand(0);
424+
// Returns true/false when we know the answer, nullopt otherwise.
425+
auto CheckASMatch = [](unsigned IID, unsigned AS) -> std::optional<bool> {
426+
if (AS == NVPTXAS::ADDRESS_SPACE_GENERIC ||
427+
AS == NVPTXAS::ADDRESS_SPACE_PARAM)
428+
return std::nullopt; // Got to check at run-time.
429+
switch (IID) {
430+
case Intrinsic::nvvm_isspacep_global:
431+
return AS == NVPTXAS::ADDRESS_SPACE_GLOBAL;
432+
case Intrinsic::nvvm_isspacep_local:
433+
return AS == NVPTXAS::ADDRESS_SPACE_LOCAL;
434+
case Intrinsic::nvvm_isspacep_shared:
435+
return AS == NVPTXAS::ADDRESS_SPACE_SHARED;
436+
case Intrinsic::nvvm_isspacep_shared_cluster:
437+
// We can't tell shared from shared_cluster at compile time from AS alone,
438+
// but it can't be either is AS is not shared.
439+
return AS == NVPTXAS::ADDRESS_SPACE_SHARED ? std::nullopt
440+
: std::optional{false};
441+
case Intrinsic::nvvm_isspacep_const:
442+
return AS == NVPTXAS::ADDRESS_SPACE_CONST;
443+
default:
444+
llvm_unreachable("Unexpected intrinsic");
445+
}
446+
};
447+
448+
switch (auto IID = II.getIntrinsicID()) {
449+
case Intrinsic::nvvm_isspacep_global:
450+
case Intrinsic::nvvm_isspacep_local:
451+
case Intrinsic::nvvm_isspacep_shared:
452+
case Intrinsic::nvvm_isspacep_shared_cluster:
453+
case Intrinsic::nvvm_isspacep_const: {
454+
auto *Ty = II.getType();
455+
unsigned AS = Op0->getType()->getPointerAddressSpace();
456+
// Peek through ASC to generic AS.
457+
// TODO: we could dig deeper through both ASCs and GEPs.
458+
if (AS == NVPTXAS::ADDRESS_SPACE_GENERIC)
459+
if (auto *ASCO = dyn_cast<AddrSpaceCastOperator>(Op0))
460+
AS = ASCO->getOperand(0)->getType()->getPointerAddressSpace();
461+
462+
if (std::optional<bool> Answer = CheckASMatch(IID, AS))
463+
return IC.replaceInstUsesWith(II, ConstantInt::get(Ty, *Answer));
464+
return nullptr; // Don't know the answer, got to check at run time.
465+
}
466+
default:
467+
return std::nullopt;
468+
}
469+
}
470+
416471
std::optional<Instruction *>
417472
NVPTXTTIImpl::instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const {
418-
if (Instruction *I = simplifyNvvmIntrinsic(&II, IC)) {
473+
if (std::optional<Instruction *> I = handleSpaceCheckIntrinsics(IC, II))
474+
return *I;
475+
if (Instruction *I = convertNvvmIntrinsicToLlvm(IC, &II))
419476
return I;
420-
}
477+
421478
return std::nullopt;
422479
}
423480

0 commit comments

Comments
 (0)