Commit 6da7dbb8 authored by Aditya Nandakumar's avatar Aditya Nandakumar
Browse files

[GlobalISel]: Allow targets to override how to widen constants during legalization

https://reviews.llvm.org/D70922

This adds a hook to allow targets to define exactly what extension
operation should be performed for widening constants. This handles cases
like widening i1 true which would end up becoming -1 which affects code
quality during combines.
Additionally, in order to stay consistent with how DAG is promoting
constants, we now signextend for byte sized types and zero extend
otherwise (by default). Targets can of course override this if
necessary.
parent 444ac341
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -1157,6 +1157,12 @@ public:
  virtual bool legalizeIntrinsic(MachineInstr &MI, MachineRegisterInfo &MRI,
                                 MachineIRBuilder &MIRBuilder) const;

  /// Return the opcode (SEXT/ZEXT/ANYEXT) that should be performed while
  /// widening a constant of type SmallTy which targets can override.
  /// For eg, the DAG does (SmallTy.isByteSized() ? G_SEXT : G_ZEXT) which
  /// will be the default.
  virtual unsigned getExtOpcodeForWideningConstant(LLT SmallTy) const;

private:
  /// Determine what action should be taken to legalize the given generic
  /// instruction opcode, type-index and type. Requires computeTables to have
+2 −0
Original line number Diff line number Diff line
@@ -137,6 +137,8 @@ public:
                      : LLT::scalar(NewEltSize);
  }

  bool isByteSized() const { return (getSizeInBits() & 7) == 0; }

  unsigned getScalarSizeInBits() const {
    assert(RawData != 0 && "Invalid Type");
    if (!IsVector) {
+9 −1
Original line number Diff line number Diff line
@@ -1675,7 +1675,15 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
  case TargetOpcode::G_CONSTANT: {
    MachineOperand &SrcMO = MI.getOperand(1);
    LLVMContext &Ctx = MIRBuilder.getMF().getFunction().getContext();
    const APInt &Val = SrcMO.getCImm()->getValue().sext(WideTy.getSizeInBits());
    unsigned ExtOpc = LI.getExtOpcodeForWideningConstant(
        MRI.getType(MI.getOperand(0).getReg()));
    assert((ExtOpc == TargetOpcode::G_ZEXT || ExtOpc == TargetOpcode::G_SEXT ||
            ExtOpc == TargetOpcode::G_ANYEXT) &&
           "Illegal Extend");
    const APInt &SrcVal = SrcMO.getCImm()->getValue();
    const APInt &Val = (ExtOpc == TargetOpcode::G_SEXT)
                           ? SrcVal.sext(WideTy.getSizeInBits())
                           : SrcVal.zext(WideTy.getSizeInBits());
    Observer.changingInstr(MI);
    SrcMO.setCImm(ConstantInt::get(Ctx, Val));

+4 −0
Original line number Diff line number Diff line
@@ -685,6 +685,10 @@ bool LegalizerInfo::legalizeIntrinsic(MachineInstr &MI,
  return true;
}

unsigned LegalizerInfo::getExtOpcodeForWideningConstant(LLT SmallTy) const {
  return SmallTy.isByteSized() ? TargetOpcode::G_SEXT : TargetOpcode::G_ZEXT;
}

/// \pre Type indices of every opcode form a dense set starting from 0.
void LegalizerInfo::verify(const MCInstrInfo &MII) const {
#ifndef NDEBUG
+1 −1
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ body: |
    %3(s1) = G_CONSTANT i1 1
    G_STORE %3(s1), %4(p0) :: (store 1)
    ; CHECK-NOT: G_CONSTANT i1
    ; CHECK: [[EXT:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
    ; CHECK: [[EXT:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
    ; CHECK: {{%[0-9]+}}:_(s1) = G_TRUNC [[EXT]](s32)
    ; CHECK-NOT: G_CONSTANT i1

Loading