LLVM: lib/Target/SPIRV/SPIRVCombinerHelper.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

12#include "llvm/IR/IntrinsicsSPIRV.h"

14

15using namespace llvm;

17

23

24

25

26

27

28

29

30

31

33 if (MI.getOpcode() != TargetOpcode::G_INTRINSIC ||

35 return false;

36

37

40 if (SubInstr->getOpcode() != TargetOpcode::G_FSUB)

41 return false;

42

43 return true;

44}

45

47

48 Register SubDestReg = MI.getOperand(2).getReg();

52 Register ResultReg = MI.getOperand(0).getReg();

53

55 Builder.buildIntrinsic(Intrinsic::spv_distance, ResultReg)

56 .addUse(SubOperand1)

57 .addUse(SubOperand2);

58

59 MI.eraseFromParent();

60}

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

77 if (STI.isShader())

78 return false;

79

80

81 Register CondReg, TrueReg, FalseReg;

84 return false;

85

86

93 return false;

95 }

96

97

99 if (DotInstr->getOpcode() != TargetOpcode::G_INTRINSIC ||

100 cast(DotInstr)->getIntrinsicID() != Intrinsic::spv_fdot) {

101 Register DotOperand1, DotOperand2;

102

105 MRI.getType(DotOperand1).isScalar() ||

106 MRI.getType(DotOperand2).isScalar())

107 return false;

108 }

109

112 return false;

113

114

115 auto AreNegatedConstantsOrSplats = [&](Register TrueReg, Register FalseReg) {

116 std::optional TrueVal, FalseVal;

119 return false;

120 APFloat TrueValNegated = TrueVal->Value;

122 return FalseVal->Value.compare(TrueValNegated) == APFloat::cmpEqual;

123 };

124

127 std::optional MulConstant;

130 if (TrueInstr->getOpcode() == TargetOpcode::G_BUILD_VECTOR &&

131 FalseInstr->getOpcode() == TargetOpcode::G_BUILD_VECTOR &&

134 if (!AreNegatedConstantsOrSplats(TrueInstr->getOperand(I).getReg(),

136 return false;

149 if (!MulConstant || !MulConstant->Value.isExactlyValue(-1.0))

150 return false;

151 } else if (!AreNegatedConstantsOrSplats(TrueReg, FalseReg))

152 return false;

153 }

154

155 return true;

156}

157

159

160 Register CondReg = MI.getOperand(1).getReg();

167 Register DotOperand1, DotOperand2;

168 if (DotInstr->getOpcode() == TargetOpcode::G_FMUL) {

171 } else {

174 }

175 Register TrueReg = MI.getOperand(2).getReg();

176 Register FalseReg = MI.getOperand(3).getReg();

178 if (TrueInstr->getOpcode() == TargetOpcode::G_FNEG ||

179 TrueInstr->getOpcode() == TargetOpcode::G_FMUL)

182

183 Register ResultReg = MI.getOperand(0).getReg();

185 Builder.buildIntrinsic(Intrinsic::spv_faceforward, ResultReg)

186 .addUse(TrueReg)

187 .addUse(DotOperand1)

188 .addUse(DotOperand2);

189

191 MI.getMF()->getSubtarget<SPIRVSubtarget>().getSPIRVGlobalRegistry();

192 auto RemoveAllUses = [&](Register Reg) {

194 for (auto &UseMI : MRI.use_instructions(Reg))

196

197

198 for (auto *MIToErase : UsesToErase)

199 MIToErase->eraseFromParent();

200 };

201

202 RemoveAllUses(CondReg);

205 RemoveAllUses(DotReg);

207 DotInstr->eraseFromParent();

208 RemoveAllUses(FalseReg);

211}

MachineInstrBuilder & UseMI

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...

Contains matchers for matching SSA Machine Instructions.

Predicate

This enumeration lists the possible predicates for CmpInst subclasses.

@ FCMP_OLT

0 1 0 0 True if ordered and less than

@ FCMP_OGT

0 0 1 0 True if ordered and greater than

@ FCMP_ULT

1 1 0 0 True if unordered or less than

@ FCMP_UGT

1 0 1 0 True if unordered or greater than

MachineRegisterInfo & MRI

MachineDominatorTree * MDT

GISelChangeObserver & Observer

MachineIRBuilder & Builder

ConstantFP - Floating Point Values [float, double].

bool isZero() const

Return true if the value is positive or negative zero.

Abstract class that contains various methods for clients to notify about changes.

DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...

Helper class to build MachineInstr.

Representation of each machine instruction.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

unsigned getNumOperands() const

Retuns the total number of operands.

LLVM_ABI void eraseFromParent()

Unlink 'this' from the containing basic block and delete it.

const MachineOperand & getOperand(unsigned i) const

Register getReg() const

getReg - Returns the register number.

Wrapper class representing virtual and physical registers.

bool matchSelectToFaceForward(MachineInstr &MI) const

This match is part of a combine that rewrites select(fcmp(dot(I, Ng), 0), N, -N) to faceforward(N,...

Definition SPIRVCombinerHelper.cpp:76

CombinerHelper(GISelChangeObserver &Observer, MachineIRBuilder &B, bool IsPreLegalize, GISelValueTracking *VT=nullptr, MachineDominatorTree *MDT=nullptr, const LegalizerInfo *LI=nullptr)

void applySPIRVFaceForward(MachineInstr &MI) const

Definition SPIRVCombinerHelper.cpp:158

SPIRVCombinerHelper(GISelChangeObserver &Observer, MachineIRBuilder &B, bool IsPreLegalize, GISelValueTracking *VT, MachineDominatorTree *MDT, const LegalizerInfo *LI, const SPIRVSubtarget &STI)

Definition SPIRVCombinerHelper.cpp:18

const SPIRVSubtarget & STI

void applySPIRVDistance(MachineInstr &MI) const

Definition SPIRVCombinerHelper.cpp:46

bool matchLengthToDistance(MachineInstr &MI) const

This match is part of a combine that rewrites length(X - Y) to distance(X, Y) (f32 (g_intrinsic lengt...

Definition SPIRVCombinerHelper.cpp:32

void invalidateMachineInstr(MachineInstr *MI)

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

operand_type_match m_Reg()

operand_type_match m_Pred()

TernaryOp_match< Src0Ty, Src1Ty, Src2Ty, TargetOpcode::G_SELECT > m_GISelect(const Src0Ty &Src0, const Src1Ty &Src1, const Src2Ty &Src2)

bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)

SpecificRegisterMatch m_SpecificReg(Register RequestedReg)

Matches a register only if it is equal to RequestedReg.

UnaryOp_match< SrcTy, TargetOpcode::G_FNEG > m_GFNeg(const SrcTy &Src)

GFCstAndRegMatch m_GFCst(std::optional< FPValueAndVReg > &FPValReg)

GFCstOrSplatGFCstMatch m_GFCstOrSplat(std::optional< FPValueAndVReg > &FPValReg)

BinaryOp_match< LHS, RHS, TargetOpcode::G_FMUL, true > m_GFMul(const LHS &L, const RHS &R)

CompareOp_match< Pred, LHS, RHS, TargetOpcode::G_FCMP > m_GFCmp(const Pred &P, const LHS &L, const RHS &R)

This is an optimization pass for GlobalISel generic memory operations.

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)

Implement std::swap in terms of BitVector swap.