LLVM: lib/CodeGen/GlobalISel/CombinerHelperCasts.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

23

24#define DEBUG_TYPE "gi-combiner"

25

26using namespace llvm;

27

32

35

36 LLT DstTy = MRI.getType(Dst);

37 LLT SrcTy = MRI.getType(Src);

38

39

41 if (DstTy != SrcTy ||

43 return false;

44

45

46

47 unsigned TruncWidth = MRI.getType(Trunc->getReg(0)).getScalarSizeInBits();

48 if (TruncWidth < 8)

49 return false;

50

52 B.buildSExtInReg(Dst, Src, TruncWidth);

53 };

54 return true;

55 }

56

57

58

59 if (DstTy == SrcTy) {

61 return true;

62 }

63

68 };

69 return true;

70 }

71

75 return true;

76 }

77

78 return false;

79}

80

85

88

89 LLT DstTy = MRI.getType(Dst);

90 LLT SrcTy = MRI.getType(Src);

91

92 if (DstTy == SrcTy) {

94 return true;

95 }

96

101 };

102 return true;

103 }

104

109 };

110 return true;

111 }

112

113 return false;

114}

115

119

122

123 LLT DstTy = MRI.getType(Dst);

124 LLT SrcTy = MRI.getType(Src);

126

127

131 return true;

132 }

133

134 return false;

135}

136

142

143 if (MRI.hasOneNonDBGUse(Ext->getReg(0)))

144 return false;

145

148 LLT DstTy = MRI.getType(Dst);

149 LLT SrcTy = MRI.getType(Src);

150

151 if (SrcTy == DstTy) {

152

154

155 return true;

156 }

157

159

160

162 return false;

163

165 B.buildInstr(Ext->getOpcode(), {Dst}, {Src});

166 };

167

168 return true;

169 }

170

172

173

175 return false;

176

178

179 return true;

180 }

181

182 return false;

183}

184

185bool CombinerHelper::isCastFree(unsigned Opcode, LLT ToTy, LLT FromTy) const {

188

189 switch (Opcode) {

190 case TargetOpcode::G_ANYEXT:

191 case TargetOpcode::G_ZEXT:

192 return TLI.isZExtFree(FromTy, ToTy, Ctx);

193 case TargetOpcode::G_TRUNC:

195 default:

196 return false;

197 }

198}

199

205

206 if (MRI.hasOneNonDBGUse(Select->getReg(0)))

207 return false;

208

210 LLT DstTy = MRI.getType(Dst);

211 LLT CondTy = MRI.getType(Select->getCondReg());

214 LLT SrcTy = MRI.getType(TrueReg);

216

218 return false;

219

220 if (!isCastFree(Cast->getOpcode(), DstTy, SrcTy))

221 return false;

222

224 auto True = B.buildInstr(Cast->getOpcode(), {DstTy}, {TrueReg});

225 auto False = B.buildInstr(Cast->getOpcode(), {DstTy}, {FalseReg});

226 B.buildSelect(Dst, Cond, True, False);

227 };

228

229 return true;

230}

231

237

240 LLT DstTy = MRI.getType(Dst);

241 LLT SrcTy = MRI.getType(Src);

242

243 if (MRI.hasOneNonDBGUse(Second->getReg(0)))

244 return false;

245

246

249 if (Second->getOpcode() == TargetOpcode::G_ZEXT) {

253 MatchInfo = [=](MachineIRBuilder &B) { B.buildZExt(Dst, Src, Flag); };

254 return true;

255 }

256

258 B.buildInstr(Second->getOpcode(), {Dst}, {Src});

259 };

260 return true;

261 }

262

263

264

265 if (First->getOpcode() == TargetOpcode::G_ANYEXT &&

267 if (Second->getOpcode() == TargetOpcode::G_ZEXT) {

271 MatchInfo = [=](MachineIRBuilder &B) { B.buildZExt(Dst, Src, Flag); };

272 return true;

273 }

275 return true;

276 }

277

278

279

280 if (Second->getOpcode() == TargetOpcode::G_ANYEXT &&

282 if (First->getOpcode() == TargetOpcode::G_ZEXT) {

286 MatchInfo = [=](MachineIRBuilder &B) { B.buildZExt(Dst, Src, Flag); };

287 return true;

288 }

290 return true;

291 }

292

293 return false;

294}

295

301

302 if (MRI.hasOneNonDBGUse(BV->getReg(0)))

303 return false;

304

306

307 LLT DstTy = MRI.getType(Dst);

308

310

311 LLT InputElemTy = MRI.getType(BV->getReg(0)).getElementType();

312

313

314

316 {TargetOpcode::G_BUILD_VECTOR, {DstTy, ElemTy}}) ||

318 !isCastFree(Cast->getOpcode(), ElemTy, InputElemTy))

319 return false;

320

324 for (unsigned I = 0; I < Elements; ++I) {

325 auto CastI =

326 B.buildInstr(Cast->getOpcode(), {ElemTy}, {BV->getSourceReg(I)});

327 Casts.push_back(CastI.getReg(0));

328 }

329

330 B.buildBuildVector(Dst, Casts);

331 };

332

333 return true;

334}

335

341

342 if (MRI.hasOneNonDBGUse(BinOp->getReg(0)))

343 return false;

344

346 LLT DstTy = MRI.getType(Dst);

347

348

350 return false;

351

353 auto LHS = B.buildTrunc(DstTy, BinOp->getLHSReg());

354 auto RHS = B.buildTrunc(DstTy, BinOp->getRHSReg());

355 B.buildInstr(BinOp->getOpcode(), {Dst}, {LHS, RHS});

356 };

357

358 return true;

359}

360

362 APInt &MatchInfo) const {

364

366

368

370 return false;

371

373 case TargetOpcode::G_TRUNC: {

375 return true;

376 }

377 default:

378 return false;

379 }

380}

381

386 Other.getOpcode() == TargetOpcode::G_SEXT_INREG);

387

389 unsigned OtherWidth = Other.getOperand(2).getImm();

390

392 Register OtherDst = Other.getOperand(0).getReg();

394

395 if (RootWidth >= OtherWidth) {

396

397

399 return false;

400

403 MRI.replaceRegWith(Dst, OtherDst);

404 Observer.finishedChangingAllUsesOfReg();

405 };

406 } else {

407

408

410 B.buildSExtInReg(Dst, Src, RootWidth);

411 };

412 }

413

414 return true;

415}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

AMDGPU Register Bank Select

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

This contains common combine transformations that may be used in a combine pass,or by the target else...

Interface for Targets to specify which operations they can successfully select and how the others sho...

Implement a low-level type suitable for MachineInstr level instruction selection.

This file declares the MachineIRBuilder class.

const SmallVectorImpl< MachineOperand > & Cond

The Input class is used to parse a yaml document into in-memory structs and vectors.

Class for arbitrary precision integers.

bool matchZextOfTrunc(const MachineOperand &MO, BuildFnTy &MatchInfo) const

Combine zext of trunc.

Definition CombinerHelperCasts.cpp:81

bool matchNonNegZext(const MachineOperand &MO, BuildFnTy &MatchInfo) const

Combine zext nneg to sext.

Definition CombinerHelperCasts.cpp:116

const TargetLowering & getTargetLowering() const

bool matchSextOfTrunc(const MachineOperand &MO, BuildFnTy &MatchInfo) const

Combine sext of trunc.

Definition CombinerHelperCasts.cpp:28

bool matchTruncateOfExt(const MachineInstr &Root, const MachineInstr &ExtMI, BuildFnTy &MatchInfo) const

Transform trunc ([asz]ext x) to x or ([asz]ext x) or (trunc x).

Definition CombinerHelperCasts.cpp:137

bool matchExtOfExt(const MachineInstr &FirstMI, const MachineInstr &SecondMI, BuildFnTy &MatchInfo) const

Definition CombinerHelperCasts.cpp:232

LLVMContext & getContext() const

bool isConstantLegalOrBeforeLegalizer(const LLT Ty) const

MachineRegisterInfo & MRI

bool isLegalOrBeforeLegalizer(const LegalityQuery &Query) const

bool matchNarrowBinop(const MachineInstr &TruncMI, const MachineInstr &BinopMI, BuildFnTy &MatchInfo) const

trunc (binop X, C) --> binop (trunc X, trunc C).

Definition CombinerHelperCasts.cpp:336

GISelChangeObserver & Observer

bool matchRedundantSextInReg(MachineInstr &Root, MachineInstr &Other, BuildFnTy &MatchInfo) const

Definition CombinerHelperCasts.cpp:382

bool matchCastOfBuildVector(const MachineInstr &CastMI, const MachineInstr &BVMI, BuildFnTy &MatchInfo) const

Definition CombinerHelperCasts.cpp:296

bool matchCastOfInteger(const MachineInstr &CastMI, APInt &MatchInfo) const

Definition CombinerHelperCasts.cpp:361

bool matchCastOfSelect(const MachineInstr &Cast, const MachineInstr &SelectMI, BuildFnTy &MatchInfo) const

Definition CombinerHelperCasts.cpp:200

Represents a binary operation, i.e, x = y op z.

Register getLHSReg() const

Register getRHSReg() const

Represents a G_BUILD_VECTOR.

Register getSrcReg() const

Represents an integer-like extending operation.

Represents an integer-like extending or truncating operation.

unsigned getNumSources() const

Returns the number of source registers.

Register getReg(unsigned Idx) const

Access the Idx'th operand as a register and return it.

constexpr unsigned getScalarSizeInBits() const

constexpr LLT getScalarType() const

This is an important class for using LLVM in a threaded context.

Helper class to build MachineInstr.

Representation of each machine instruction.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

bool getFlag(MIFlag Flag) const

Return whether an MI flag is set.

const MachineOperand & getOperand(unsigned i) const

MachineOperand class - Representation of each machine instruction operand.

Register getReg() const

getReg - Returns the register number.

Wrapper class representing virtual and physical registers.

void push_back(const T &Elt)

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

virtual bool isZExtFree(Type *FromTy, Type *ToTy) const

Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...

virtual bool isTruncateFree(Type *FromTy, Type *ToTy) const

Return true if it's free to truncate a value of type FromTy to type ToTy.

This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...

This is an optimization pass for GlobalISel generic memory operations.

std::function< void(MachineIRBuilder &)> BuildFnTy

LLVM_ABI MVT getMVTForLLT(LLT Ty)

Get a rough equivalent of an MVT for a given LLT.

LLVM_ABI MachineInstr * getDefIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)

Find the def instruction for Reg, folding away any trivial copies.

LLVM_ABI const APInt & getIConstantFromReg(Register VReg, const MachineRegisterInfo &MRI)

VReg is defined by a G_CONSTANT, return the corresponding value.

LLVM_ABI bool canReplaceReg(Register DstReg, Register SrcReg, MachineRegisterInfo &MRI)

Check if DstReg can be replaced with SrcReg depending on the register constraints.

@ First

Helpers to iterate all locations in the MemoryEffectsBase class.

decltype(auto) cast(const From &Val)

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