diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h --- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h +++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h @@ -23,6 +23,8 @@ class RISCVLegalizerInfo : public LegalizerInfo { public: RISCVLegalizerInfo(const RISCVSubtarget &ST); + + bool legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI) const override; }; } // end namespace llvm #endif diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp --- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp @@ -12,6 +12,7 @@ #include "RISCVLegalizerInfo.h" #include "RISCVSubtarget.h" +#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" #include "llvm/CodeGen/TargetOpcodes.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/IR/DerivedTypes.h" @@ -51,17 +52,23 @@ .clampScalar(1, s32, XLenLLT) .clampScalar(0, s32, XLenLLT); - if (ST.is64Bit()) + if (ST.is64Bit()) { getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT}) .legalFor({{XLenLLT, s32}}) .maxScalar(0, XLenLLT); - else + + getActionDefinitionsBuilder(G_SEXT_INREG) + .customFor({XLenLLT}) + .maxScalar(0, XLenLLT) + .lower(); + } else { getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT}) .maxScalar(0, XLenLLT); - getActionDefinitionsBuilder(G_SEXT_INREG) - .maxScalar(0, XLenLLT) - .lower(); + getActionDefinitionsBuilder(G_SEXT_INREG) + .maxScalar(0, XLenLLT) + .lower(); + } // Merge/Unmerge for (unsigned Op : {G_MERGE_VALUES, G_UNMERGE_VALUES}) { @@ -162,3 +169,23 @@ getLegacyLegalizerInfo().computeTables(); } + +bool RISCVLegalizerInfo::legalizeCustom(LegalizerHelper &Helper, + MachineInstr &MI) const { + switch (MI.getOpcode()) { + default: + // No idea what to do. + return false; + case TargetOpcode::G_SEXT_INREG: { + // Source size of 32 is sext.w. + int64_t SizeInBits = MI.getOperand(2).getImm(); + if (SizeInBits == 32) + return true; + + return Helper.lower(MI, 0, /* Unused hint type */ LLT()) == + LegalizerHelper::Legalized; + } + } + + llvm_unreachable("expected switch to return"); +} diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-div.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-div.mir --- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-div.mir +++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-div.mir @@ -145,14 +145,10 @@ ; CHECK-I-LABEL: name: sdiv_i32 ; CHECK-I: [[COPY:%[0-9]+]]:_(s64) = COPY $x10 ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11 - ; CHECK-I-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 32 - ; CHECK-I-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[COPY]], [[C]](s64) - ; CHECK-I-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[SHL]], [[C]](s64) - ; CHECK-I-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 32 - ; CHECK-I-NEXT: [[SHL1:%[0-9]+]]:_(s64) = G_SHL [[COPY1]], [[C1]](s64) - ; CHECK-I-NEXT: [[ASHR1:%[0-9]+]]:_(s64) = G_ASHR [[SHL1]], [[C1]](s64) - ; CHECK-I-NEXT: $x10 = COPY [[ASHR]](s64) - ; CHECK-I-NEXT: $x11 = COPY [[ASHR1]](s64) + ; CHECK-I-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 32 + ; CHECK-I-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 32 + ; CHECK-I-NEXT: $x10 = COPY [[SEXT_INREG]](s64) + ; CHECK-I-NEXT: $x11 = COPY [[SEXT_INREG1]](s64) ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__divdi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10 ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10 ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s64) diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-icmp.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-icmp.mir --- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-icmp.mir +++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-icmp.mir @@ -86,13 +86,9 @@ ; CHECK-LABEL: name: cmp_sgt_i32 ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x10 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 32 - ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[COPY]], [[C]](s64) - ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[SHL]], [[C]](s64) - ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 32 - ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s64) = G_SHL [[COPY1]], [[C1]](s64) - ; CHECK-NEXT: [[ASHR1:%[0-9]+]]:_(s64) = G_ASHR [[SHL1]], [[C1]](s64) - ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s64) = G_ICMP intpred(sgt), [[ASHR]](s64), [[ASHR1]] + ; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 32 + ; CHECK-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 32 + ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s64) = G_ICMP intpred(sgt), [[SEXT_INREG]](s64), [[SEXT_INREG1]] ; CHECK-NEXT: $x10 = COPY [[ICMP]](s64) ; CHECK-NEXT: PseudoRET implicit $x10 %0:_(s64) = COPY $x10 @@ -274,13 +270,9 @@ ; CHECK-LABEL: name: cmp_slt_i32 ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x10 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 32 - ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[COPY]], [[C]](s64) - ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[SHL]], [[C]](s64) - ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 32 - ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s64) = G_SHL [[COPY1]], [[C1]](s64) - ; CHECK-NEXT: [[ASHR1:%[0-9]+]]:_(s64) = G_ASHR [[SHL1]], [[C1]](s64) - ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s64) = G_ICMP intpred(slt), [[ASHR]](s64), [[ASHR1]] + ; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 32 + ; CHECK-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 32 + ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s64) = G_ICMP intpred(slt), [[SEXT_INREG]](s64), [[SEXT_INREG1]] ; CHECK-NEXT: $x10 = COPY [[ICMP]](s64) ; CHECK-NEXT: PseudoRET implicit $x10 %0:_(s64) = COPY $x10 @@ -462,13 +454,9 @@ ; CHECK-LABEL: name: cmp_sge_i32 ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x10 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 32 - ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[COPY]], [[C]](s64) - ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[SHL]], [[C]](s64) - ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 32 - ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s64) = G_SHL [[COPY1]], [[C1]](s64) - ; CHECK-NEXT: [[ASHR1:%[0-9]+]]:_(s64) = G_ASHR [[SHL1]], [[C1]](s64) - ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s64) = G_ICMP intpred(sge), [[ASHR]](s64), [[ASHR1]] + ; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 32 + ; CHECK-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 32 + ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s64) = G_ICMP intpred(sge), [[SEXT_INREG]](s64), [[SEXT_INREG1]] ; CHECK-NEXT: $x10 = COPY [[ICMP]](s64) ; CHECK-NEXT: PseudoRET implicit $x10 %0:_(s64) = COPY $x10 @@ -650,13 +638,9 @@ ; CHECK-LABEL: name: cmp_sle_i32 ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x10 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 32 - ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[COPY]], [[C]](s64) - ; CHECK-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[SHL]], [[C]](s64) - ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 32 - ; CHECK-NEXT: [[SHL1:%[0-9]+]]:_(s64) = G_SHL [[COPY1]], [[C1]](s64) - ; CHECK-NEXT: [[ASHR1:%[0-9]+]]:_(s64) = G_ASHR [[SHL1]], [[C1]](s64) - ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s64) = G_ICMP intpred(sle), [[ASHR]](s64), [[ASHR1]] + ; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 32 + ; CHECK-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 32 + ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s64) = G_ICMP intpred(sle), [[SEXT_INREG]](s64), [[SEXT_INREG1]] ; CHECK-NEXT: $x10 = COPY [[ICMP]](s64) ; CHECK-NEXT: PseudoRET implicit $x10 %0:_(s64) = COPY $x10 diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-rem.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-rem.mir --- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-rem.mir +++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-rem.mir @@ -145,14 +145,10 @@ ; CHECK-I-LABEL: name: srem_i32 ; CHECK-I: [[COPY:%[0-9]+]]:_(s64) = COPY $x10 ; CHECK-I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11 - ; CHECK-I-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 32 - ; CHECK-I-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[COPY]], [[C]](s64) - ; CHECK-I-NEXT: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[SHL]], [[C]](s64) - ; CHECK-I-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 32 - ; CHECK-I-NEXT: [[SHL1:%[0-9]+]]:_(s64) = G_SHL [[COPY1]], [[C1]](s64) - ; CHECK-I-NEXT: [[ASHR1:%[0-9]+]]:_(s64) = G_ASHR [[SHL1]], [[C1]](s64) - ; CHECK-I-NEXT: $x10 = COPY [[ASHR]](s64) - ; CHECK-I-NEXT: $x11 = COPY [[ASHR1]](s64) + ; CHECK-I-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 32 + ; CHECK-I-NEXT: [[SEXT_INREG1:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY1]], 32 + ; CHECK-I-NEXT: $x10 = COPY [[SEXT_INREG]](s64) + ; CHECK-I-NEXT: $x11 = COPY [[SEXT_INREG1]](s64) ; CHECK-I-NEXT: PseudoCALL target-flags(riscv-call) &__moddi3, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10 ; CHECK-I-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x10 ; CHECK-I-NEXT: $x10 = COPY [[COPY2]](s64)