24
24
#include " llvm/CodeGen/GlobalISel/Utils.h"
25
25
#include " llvm/CodeGen/MachineRegisterInfo.h"
26
26
#include " llvm/CodeGen/Register.h"
27
+ #include " llvm/CodeGen/TargetOpcodes.h"
27
28
#include " llvm/IR/Constants.h"
28
29
#include " llvm/Support/Debug.h"
29
30
@@ -235,12 +236,12 @@ class LegalizationArtifactCombiner {
235
236
236
237
Builder.setInstr (MI);
237
238
Register DstReg = MI.getOperand (0 ).getReg ();
239
+ const LLT DstTy = MRI.getType (DstReg);
238
240
Register SrcReg = lookThroughCopyInstrs (MI.getOperand (1 ).getReg ());
239
241
240
242
// Try to fold trunc(g_constant) when the smaller constant type is legal.
241
243
auto *SrcMI = MRI.getVRegDef (SrcReg);
242
244
if (SrcMI->getOpcode () == TargetOpcode::G_CONSTANT) {
243
- const LLT DstTy = MRI.getType (DstReg);
244
245
if (isInstLegal ({TargetOpcode::G_CONSTANT, {DstTy}})) {
245
246
auto &CstVal = SrcMI->getOperand (1 );
246
247
Builder.buildConstant (
@@ -256,7 +257,6 @@ class LegalizationArtifactCombiner {
256
257
if (auto *SrcMerge = dyn_cast<GMerge>(SrcMI)) {
257
258
const Register MergeSrcReg = SrcMerge->getSourceReg (0 );
258
259
const LLT MergeSrcTy = MRI.getType (MergeSrcReg);
259
- const LLT DstTy = MRI.getType (DstReg);
260
260
261
261
// We can only fold if the types are scalar
262
262
const unsigned DstSize = DstTy.getSizeInBits ();
@@ -325,6 +325,23 @@ class LegalizationArtifactCombiner {
325
325
return true ;
326
326
}
327
327
328
+ // trunc(ext x) -> x
329
+ ArtifactValueFinder Finder (MRI, Builder, LI);
330
+ if (Register FoundReg =
331
+ Finder.findValueFromDef (DstReg, 0 , DstTy.getSizeInBits ())) {
332
+ LLT FoundRegTy = MRI.getType (FoundReg);
333
+ if (DstTy == FoundRegTy) {
334
+ LLVM_DEBUG (dbgs () << " .. Combine G_TRUNC(G_[S,Z,ANY]EXT/G_TRUNC...): "
335
+ << MI;);
336
+
337
+ replaceRegOrBuildCopy (DstReg, FoundReg, MRI, Builder, UpdatedDefs,
338
+ Observer);
339
+ UpdatedDefs.push_back (DstReg);
340
+ markInstAndDefDead (MI, *MRI.getVRegDef (SrcReg), DeadInsts);
341
+ return true ;
342
+ }
343
+ }
344
+
328
345
return false ;
329
346
}
330
347
@@ -719,6 +736,55 @@ class LegalizationArtifactCombiner {
719
736
return Register ();
720
737
}
721
738
739
+ // / Given an G_SEXT, G_ZEXT, G_ANYEXT op \p MI and a start bit and
740
+ // / size, try to find the origin of the value defined by that start
741
+ // / position and size.
742
+ // /
743
+ // / \returns a register with the requested size, or the current best
744
+ // / register found during the current query.
745
+ Register findValueFromExt (MachineInstr &MI, unsigned StartBit,
746
+ unsigned Size) {
747
+ assert (MI.getOpcode () == TargetOpcode::G_SEXT ||
748
+ MI.getOpcode () == TargetOpcode::G_ZEXT ||
749
+ MI.getOpcode () == TargetOpcode::G_ANYEXT);
750
+ assert (Size > 0 );
751
+
752
+ Register SrcReg = MI.getOperand (1 ).getReg ();
753
+ LLT SrcType = MRI.getType (SrcReg);
754
+ unsigned SrcSize = SrcType.getSizeInBits ();
755
+
756
+ // Currently we don't go into vectors.
757
+ if (!SrcType.isScalar ())
758
+ return CurrentBest;
759
+
760
+ if (StartBit + Size > SrcSize)
761
+ return CurrentBest;
762
+
763
+ if (StartBit == 0 && SrcType.getSizeInBits () == Size)
764
+ CurrentBest = SrcReg;
765
+ return findValueFromDefImpl (SrcReg, StartBit, Size);
766
+ }
767
+
768
+ // / Given an G_TRUNC op \p MI and a start bit and size, try to find
769
+ // / the origin of the value defined by that start position and size.
770
+ // /
771
+ // / \returns a register with the requested size, or the current best
772
+ // / register found during the current query.
773
+ Register findValueFromTrunc (MachineInstr &MI, unsigned StartBit,
774
+ unsigned Size) {
775
+ assert (MI.getOpcode () == TargetOpcode::G_TRUNC);
776
+ assert (Size > 0 );
777
+
778
+ Register SrcReg = MI.getOperand (1 ).getReg ();
779
+ LLT SrcType = MRI.getType (SrcReg);
780
+
781
+ // Currently we don't go into vectors.
782
+ if (!SrcType.isScalar ())
783
+ return CurrentBest;
784
+
785
+ return findValueFromDefImpl (SrcReg, StartBit, Size);
786
+ }
787
+
722
788
// / Internal implementation for findValueFromDef(). findValueFromDef()
723
789
// / initializes some data like the CurrentBest register, which this method
724
790
// / and its callees rely upon.
@@ -759,6 +825,12 @@ class LegalizationArtifactCombiner {
759
825
Size);
760
826
case TargetOpcode::G_INSERT:
761
827
return findValueFromInsert (*Def, StartBit, Size);
828
+ case TargetOpcode::G_TRUNC:
829
+ return findValueFromTrunc (*Def, StartBit, Size);
830
+ case TargetOpcode::G_SEXT:
831
+ case TargetOpcode::G_ZEXT:
832
+ case TargetOpcode::G_ANYEXT:
833
+ return findValueFromExt (*Def, StartBit, Size);
762
834
default :
763
835
return CurrentBest;
764
836
}
0 commit comments