Skip to content

Commit

Permalink
[SOL] Create explicit sign extension instruction (#114)
Browse files Browse the repository at this point in the history
* Create explicit sign extension instruction
  • Loading branch information
LucasSte authored Dec 3, 2024
1 parent a802634 commit f602770
Show file tree
Hide file tree
Showing 9 changed files with 196 additions and 20 deletions.
13 changes: 9 additions & 4 deletions llvm/lib/Target/SBF/SBFISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -933,24 +933,29 @@ SBFTargetLowering::EmitSubregExt(MachineInstr &MI, MachineBasicBlock *BB,
unsigned Reg, bool isSigned) const {
const TargetInstrInfo &TII = *BB->getParent()->getSubtarget().getInstrInfo();
const TargetRegisterClass *RC = getRegClassFor(MVT::i64);
int RShiftOp = isSigned ? SBF::SRA_ri : SBF::SRL_ri;
MachineFunction *F = BB->getParent();
DebugLoc DL = MI.getDebugLoc();

MachineRegisterInfo &RegInfo = F->getRegInfo();

if (!isSigned) {
unsigned MovOp =
Subtarget->getHasExplicitSignExt()
? SBF::MOV_rr : SBF::MOV_32_64;
Register PromotedReg0 = RegInfo.createVirtualRegister(RC);
BuildMI(BB, DL, TII.get(SBF::MOV_32_64), PromotedReg0).addReg(Reg);
BuildMI(BB, DL, TII.get(MovOp), PromotedReg0).addReg(Reg);
return PromotedReg0;
}
Register PromotedReg0 = RegInfo.createVirtualRegister(RC);
BuildMI(BB, DL, TII.get(SBF::MOV_32_64), PromotedReg0).addReg(Reg);
if (Subtarget->getHasExplicitSignExt())
return PromotedReg0;

Register PromotedReg1 = RegInfo.createVirtualRegister(RC);
Register PromotedReg2 = RegInfo.createVirtualRegister(RC);
BuildMI(BB, DL, TII.get(SBF::MOV_32_64), PromotedReg0).addReg(Reg);
BuildMI(BB, DL, TII.get(SBF::SLL_ri), PromotedReg1)
.addReg(PromotedReg0).addImm(32);
BuildMI(BB, DL, TII.get(RShiftOp), PromotedReg2)
BuildMI(BB, DL, TII.get(SBF::SRA_ri), PromotedReg2)
.addReg(PromotedReg1).addImm(32);

return PromotedReg2;
Expand Down
12 changes: 10 additions & 2 deletions llvm/lib/Target/SBF/SBFInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,24 @@ using namespace llvm;
SBFInstrInfo::SBFInstrInfo()
: SBFGenInstrInfo(SBF::ADJCALLSTACKDOWN, SBF::ADJCALLSTACKUP) {}

void SBFInstrInfo::setHasExplicitSignExt(bool HasExplicitSext) {
this->HasExplicitSignExt = HasExplicitSext;
}

void SBFInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
const DebugLoc &DL, MCRegister DestReg,
MCRegister SrcReg, bool KillSrc) const {
if (SBF::GPRRegClass.contains(DestReg, SrcReg))
BuildMI(MBB, I, DL, get(SBF::MOV_rr), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc));
else if (SBF::GPR32RegClass.contains(DestReg, SrcReg))
BuildMI(MBB, I, DL, get(SBF::MOV_rr_32), DestReg)
else if (SBF::GPR32RegClass.contains(DestReg, SrcReg)) {
unsigned OpCode =
HasExplicitSignExt ? SBF::MOV_rr_32_no_sext_v2
: SBF::MOV_rr_32_no_sext_v1;
BuildMI(MBB, I, DL, get(OpCode), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc));
}
else
llvm_unreachable("Impossible reg-to-reg copy");
}
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/Target/SBF/SBFInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@ class SBFInstrInfo : public SBFGenInstrInfo {
MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
const DebugLoc &DL,
int *BytesAdded = nullptr) const override;
void setHasExplicitSignExt(bool HasExplicitSext);

private:
void expandMEMCPY(MachineBasicBlock::iterator) const;

bool HasExplicitSignExt;
};
}

Expand Down
59 changes: 47 additions & 12 deletions llvm/lib/Target/SBF/SBFInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ def SBFNoCallxSrc : Predicate<"!Subtarget->getCallXRegSrc()">;
def SBFPqrInstr : Predicate<"Subtarget->getHasPqrClass()">;
def SBFNoPqrInstr : Predicate<"!Subtarget->getHasPqrClass()">;
def SBFHasStoreImm : Predicate<"Subtarget->getHasStoreImm()">;
def SBFExplicitSignExt : Predicate<"Subtarget->getHasExplicitSignExt()">;
def SBFNoExplicitSignExt : Predicate<"!Subtarget->getHasExplicitSignExt()">;

def brtarget : Operand<OtherVT> {
let PrintMethod = "printBrTargetOperand";
Expand Down Expand Up @@ -415,16 +417,26 @@ def MOV_ri : MATH_RI<SBF_ALU64, SBF_MOV,
(ins i64imm:$imm),
"mov64 $dst, $imm",
[(set GPR:$dst, (i64 i64immSExt32:$imm))]>;
def MOV_rr_32 : MATH_RR<SBF_ALU, SBF_MOV,
(outs GPR32:$dst),
(ins GPR32:$src),
"mov32 $dst, $src",
[]>;

def MOV_ri_32 : MATH_RI<SBF_ALU, SBF_MOV,
(outs GPR32:$dst),
(ins i32imm:$imm),
"mov32 $dst, $imm",
[(set GPR32:$dst, (i32 i32immSExt32:$imm))]>;

let Predicates = [SBFExplicitSignExt], DecoderNamespace = "SBFv2" in {
def MOV_rr_32_no_sext_v2 : MATH_RR<SBF_ALU64, SBF_MOV,
(outs GPR32:$dst),
(ins GPR32:$src),
"mov64 $dst, $src",
[]>;
}

def MOV_rr_32_no_sext_v1 : MATH_RR<SBF_ALU, SBF_MOV,
(outs GPR32:$dst),
(ins GPR32:$src),
"mov32 $dst, $src",
[]>, Requires<[SBFNoExplicitSignExt]>;
}

def FI_ri
Expand Down Expand Up @@ -993,10 +1005,13 @@ let Constraints = "$dst = $src" in {
}
}

let isCodeGenOnly = 1 in {
let DecoderNamespace = "SBFv2" in {
def MOV_32_64 : MATH_RR<SBF_ALU, SBF_MOV,
(outs GPR:$dst), (ins GPR32:$src),
"mov32 $dst, $src", []>;
}

let isCodeGenOnly = 1 in {
def MOV_32_64_addr : MATH_RI<SBF_ALU, SBF_MOV,
(outs GPR:$dst), (ins u64imm:$imm),
"mov32 $dst, $imm", []>, Requires<[SBFNoLddw]>;
Expand All @@ -1023,19 +1038,39 @@ def : Pat<(SBFWrapper tglobaladdr:$in),
(HOR_addr (MOV_32_64_addr tglobaladdr:$in),
tglobaladdr:$in)>, Requires<[SBFNoLddw]>;

// SBFv2 sign extension
def : Pat<(i64 (sext GPR32:$src)),
(MOV_32_64 GPR32:$src)>, Requires<[SBFExplicitSignExt]>;

// SBFv1 sign extension
def : Pat<(i64 (sext GPR32:$src)),
(SRA_ri (SLL_ri (MOV_32_64 GPR32:$src), 32), 32)>;
(SRA_ri (SLL_ri (MOV_32_64 GPR32:$src), 32), 32)>,
Requires<[SBFNoExplicitSignExt]>;

// SBFv2 zero extension
def : Pat<(i64 (zext GPR32:$src)), (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
GPR32:$src, sub_32)>, Requires<[SBFExplicitSignExt]>;

def : Pat<(i64 (zext GPR32:$src)), (MOV_32_64 GPR32:$src)>;
// SBFv1 zero extension
def : Pat<(i64 (zext GPR32:$src)), (MOV_32_64 GPR32:$src)>,
Requires<[SBFNoExplicitSignExt]>;

// For i64 -> i32 truncation, use the 32-bit subregister directly.
// SBFv2 truncation
def : Pat<(i32 (trunc GPR:$src)),
(i32 (EXTRACT_SUBREG GPR:$src, sub_32))>;
(AND_ri_32 (i32 (EXTRACT_SUBREG GPR:$src, sub_32)),
(i32 0xffffffff))>, Requires<[SBFExplicitSignExt]>;

// SBFv1 truncation
def : Pat<(i32 (trunc GPR:$src)),
(i32 (EXTRACT_SUBREG GPR:$src, sub_32))>, Requires<[SBFNoExplicitSignExt]>;

// SBFv2 anyext
def : Pat<(i64 (anyext GPR32:$src)),
(MOV_32_64 GPR32:$src)>, Requires<[SBFExplicitSignExt]>;

// For i32 -> i64 anyext, we don't care about the high bits.
// SBFv1 anyext
def : Pat<(i64 (anyext GPR32:$src)),
(INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$src, sub_32)>;
(INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$src, sub_32)>, Requires<[SBFNoExplicitSignExt]>;

class STORE32<SBFWidthModifer SizeOp, string Mnemonic, list<dag> Pattern>
: TYPE_LD_ST<SBF_MEM.Value, SizeOp.Value,
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/SBF/SBFSubtarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ SBFSubtarget &SBFSubtarget::initializeSubtargetDependencies(const Triple &TT,
StringRef FS) {
initializeEnvironment(TT);
initSubtargetFeatures(CPU, FS);
InstrInfo.setHasExplicitSignExt(HasExplicitSignExt);
return *this;
}

Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/SBF/SBFSubtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ class SBFSubtarget : public SBFGenSubtargetInfo {
// Whether we have store imm instructions
bool HasStoreImm;

// Whether we have the explicit sign extension instruction (mov32)
bool HasExplicitSignExt;

public:
// This constructor initializes the data members to match that
// of the specified triple.
Expand All @@ -105,6 +108,7 @@ class SBFSubtarget : public SBFGenSubtargetInfo {
return HasDynamicFrames && NewCallConvention;
}
bool getHasStoreImm() const { return HasStoreImm; }
bool getHasExplicitSignExt() const { return HasExplicitSignExt; }
const SBFInstrInfo *getInstrInfo() const override { return &InstrInfo; }
const SBFFrameLowering *getFrameLowering() const override {
return &FrameLowering;
Expand Down
5 changes: 4 additions & 1 deletion llvm/lib/Target/SBF/SBFTargetFeatures.td
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ def FeatureCallConv : SubtargetFeature<"new-call-conv", "NewCallConvention", "tr
def FeatureStoreImm : SubtargetFeature<"store-imm", "HasStoreImm", "true",
"Enable store imm instructions">;

def FeatureExplicitSext : SubtargetFeature<"explicit-sext", "HasExplicitSignExt",
"true", "Enable the explicit sign extension instruction mov32">;

class Proc<string Name, list<SubtargetFeature> Features>
: Processor<Name, NoItineraries, Features>;

Expand All @@ -55,4 +58,4 @@ def : Proc<"v2", []>;
def : Proc<"v3", [ALU32]>;
def : Proc<"sbfv2", [FeatureDynamicFrames, FeatureRelocAbs64, FeatureStaticSyscalls,
FeatureDisableNeg, FeatureReverseSubImm, FeatureDisableLddw, FeatureCallxRegSrc,
FeaturePqrInstr, FeatureCallConv]>;
FeaturePqrInstr, FeatureCallConv, FeatureExplicitSext]>;
110 changes: 110 additions & 0 deletions llvm/test/CodeGen/SBF/explicit-sign-ext.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
; RUN: llc -march=sbf -mattr=+alu32 < %s | FileCheck --check-prefixes=CHECK-v1,CHECK %s
; RUN: llc -march=sbf -mattr=+alu32,+explicit-sext < %s | FileCheck --check-prefixes=CHECK-v2,CHECK %s


define dso_local i64 @my_sext(i32 %a) local_unnamed_addr #0 {
entry:
; CHECK-LABEL: my_sext
%res = sext i32 %a to i64

; CHECK-v1: mov32 r0, w1
; CHECK-v1: lsh64 r0, 32
; CHECK-v1: arsh64 r0, 32

; CHECK-v2: mov32 r0, w1
ret i64 %res
}

define dso_local i64 @my_zext(i32 %a) local_unnamed_addr #0 {
entry:
; CHECK-LABEL: my_zext
%res = zext i32 %a to i64

; CHECK-v1: mov32 r0, w1
; CHECK-v2: mov64 w0, w1

ret i64 %res
}

define dso_local i32 @my_trunc(i64 %a) local_unnamed_addr #0 {
entry:
; CHECK-LABEL: my_trunc
%res = trunc i64 %a to i32

; CHECK-v1: mov64 r0, r1
; CHECK-v2: mov64 r0, r1
; CHECK-v2: and32 w0, -1
ret i32 %res
}

define dso_local i32 @copy_phys(i32 %a) local_unnamed_addr #0 {
entry:
; CHECK-LABEL: copy_phys
%res = add i32 %a, 2
%b = sub i32 %res, 5
; CHECK-v1: mov32 w0, w1
; CHECK-v2: mov64 w0, w1
ret i32 %b
}

define dso_local i32 @select_cc_imm(i32 %a, i32 %c, i32 %d) local_unnamed_addr #0 {
entry:
; CHECK-LABEL: select_cc_imm
%cmp = icmp sgt i32 %a, 10
; CHECK-v1: mov32 w0, w2
; CHECK-v2: mov64 w0, w2

; CHECK-v1: mov32 r1, w1
; CHECK-v1: lsh64 r1, 32
; CHECK-v1: arsh64 r1, 32
; CHECK-v2: mov32 r1, w1

%c.d = select i1 %cmp, i32 %c, i32 %d
; CHECK-v1: mov32 w0, w3
; CHECK-v2: mov64 w0, w3

ret i32 %c.d
}

define dso_local i32 @select_cc_reg(i32 %a, i32 %b, i32 %c, i32 %d) local_unnamed_addr #0 {
entry:
; CHECK-LABEL: select_cc_reg
%cmp = icmp sgt i32 %a, %b
; CHECK-v1: mov32 w0, w3
; CHECK-v2: mov64 w0, w3

; CHECK-v1: mov32 r1, w1
; CHECK-v1: lsh64 r1, 32
; CHECK-v1: arsh64 r1, 32
; CHECK-v2: mov32 r1, w1

; CHECK-v1: mov32 r2, w2
; CHECK-v1: lsh64 r2, 32
; CHECK-v1: arsh64 r2, 32
; CHECK-v2: mov32 r2, w2

%c.d = select i1 %cmp, i32 %c, i32 %d
; CHECK-v1: mov32 w0, w4
; CHECK-v2: mov64 w0, w4
ret i32 %c.d
}

define dso_local i64 @select_cc_imm_64(i32 %a, i64 %c, i64 %d) local_unnamed_addr #0 {
entry:
; CHECK-LABEL: select_cc_imm_64
; CHECK-v1: mov64 r0, r2
%cmp = icmp sgt i32 %a, 10
%c.d = select i1 %cmp, i64 %c, i64 %d
; CHECK: mov64 r0, r3
ret i64 %c.d
}

define dso_local i64 @select_cc_reg_64(i32 %a, i32 %b, i64 %c, i64 %d) local_unnamed_addr #0 {
entry:
; CHECK-LABEL: select_cc_reg_64
; CHECK: mov64 r0, r3
%cmp = icmp sgt i32 %a, %b
%c.d = select i1 %cmp, i64 %c, i64 %d
; CHECK: mov64 r0, r4
ret i64 %c.d
}
8 changes: 8 additions & 0 deletions llvm/test/MC/SBF/sbf-alu.s
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,10 @@ mov64 r0, r9
# CHECK-ASM-NEW: encoding: [0xbf,0x23,0x00,0x00,0x00,0x00,0x00,0x00]
mov64 r3, r2

# CHECK-OBJ-NEW: mov64 r3, r2
# CHECK-ASM-NEW: encoding: [0xbf,0x23,0x00,0x00,0x00,0x00,0x00,0x00]
mov64 w3, w2

# CHECK-OBJ-NEW: mov64 r3, 0x7b
# CHECK-ASM-NEW: encoding: [0xb7,0x03,0x00,0x00,0x7b,0x00,0x00,0x00]
mov64 r3, 123
Expand All @@ -303,6 +307,10 @@ mov64 r5, -123
# CHECK-ASM-NEW: encoding: [0xbc,0x26,0x00,0x00,0x00,0x00,0x00,0x00]
mov32 w6, w2

# CHECK-OBJ-NEW: mov32 w6, w2
# CHECK-ASM-NEW: encoding: [0xbc,0x26,0x00,0x00,0x00,0x00,0x00,0x00]
mov32 r6, w2

# CHECK-OBJ-NEW: mov32 w5, -0x7b
# CHECK-ASM-NEW: encoding: [0xb4,0x05,0x00,0x00,0x85,0xff,0xff,0xff]
mov32 w5, -123
Expand Down

0 comments on commit f602770

Please sign in to comment.