mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-12 13:30:51 +00:00
Optimize:
r1025 = s/zext r1024, 4 r1026 = extract_subreg r1025, 4 to: r1026 = copy r1024 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122925 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c010e61ae1
commit
0b71d3972d
@ -428,31 +428,47 @@ void InstrEmitter::EmitSubregNode(SDNode *Node,
|
||||
|
||||
// Figure out the register class to create for the destreg.
|
||||
unsigned VReg = getVR(Node->getOperand(0), VRBaseMap);
|
||||
const TargetRegisterClass *TRC = MRI->getRegClass(VReg);
|
||||
const TargetRegisterClass *SRC = TRC->getSubRegisterRegClass(SubIdx);
|
||||
assert(SRC && "Invalid subregister index in EXTRACT_SUBREG");
|
||||
MachineInstr *DefMI = MRI->getVRegDef(VReg);
|
||||
unsigned SrcReg, DstReg, DefSubIdx;
|
||||
if (DefMI &&
|
||||
TII->isCoalescableExtInstr(*DefMI, SrcReg, DstReg, DefSubIdx) &&
|
||||
SubIdx == DefSubIdx) {
|
||||
// Optimize these:
|
||||
// r1025 = s/zext r1024, 4
|
||||
// r1026 = extract_subreg r1025, 4
|
||||
// to a copy
|
||||
// r1026 = copy r1024
|
||||
const TargetRegisterClass *TRC = MRI->getRegClass(SrcReg);
|
||||
VRBase = MRI->createVirtualRegister(TRC);
|
||||
BuildMI(*MBB, InsertPos, Node->getDebugLoc(),
|
||||
TII->get(TargetOpcode::COPY), VRBase).addReg(SrcReg);
|
||||
} else {
|
||||
const TargetRegisterClass *TRC = MRI->getRegClass(VReg);
|
||||
const TargetRegisterClass *SRC = TRC->getSubRegisterRegClass(SubIdx);
|
||||
assert(SRC && "Invalid subregister index in EXTRACT_SUBREG");
|
||||
|
||||
// Figure out the register class to create for the destreg.
|
||||
// Note that if we're going to directly use an existing register,
|
||||
// it must be precisely the required class, and not a subclass
|
||||
// thereof.
|
||||
if (VRBase == 0 || SRC != MRI->getRegClass(VRBase)) {
|
||||
// Create the reg
|
||||
assert(SRC && "Couldn't find source register class");
|
||||
VRBase = MRI->createVirtualRegister(SRC);
|
||||
// Figure out the register class to create for the destreg.
|
||||
// Note that if we're going to directly use an existing register,
|
||||
// it must be precisely the required class, and not a subclass
|
||||
// thereof.
|
||||
if (VRBase == 0 || SRC != MRI->getRegClass(VRBase)) {
|
||||
// Create the reg
|
||||
assert(SRC && "Couldn't find source register class");
|
||||
VRBase = MRI->createVirtualRegister(SRC);
|
||||
}
|
||||
|
||||
// Create the extract_subreg machine instruction.
|
||||
MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(),
|
||||
TII->get(TargetOpcode::COPY), VRBase);
|
||||
|
||||
// Add source, and subreg index
|
||||
AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap, /*IsDebug=*/false,
|
||||
IsClone, IsCloned);
|
||||
assert(TargetRegisterInfo::isVirtualRegister(MI->getOperand(1).getReg())&&
|
||||
"Cannot yet extract from physregs");
|
||||
MI->getOperand(1).setSubReg(SubIdx);
|
||||
MBB->insert(InsertPos, MI);
|
||||
}
|
||||
|
||||
// Create the extract_subreg machine instruction.
|
||||
MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(),
|
||||
TII->get(TargetOpcode::COPY), VRBase);
|
||||
|
||||
// Add source, and subreg index
|
||||
AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap, /*IsDebug=*/false,
|
||||
IsClone, IsCloned);
|
||||
assert(TargetRegisterInfo::isVirtualRegister(MI->getOperand(1).getReg()) &&
|
||||
"Cannot yet extract from physregs");
|
||||
MI->getOperand(1).setSubReg(SubIdx);
|
||||
MBB->insert(InsertPos, MI);
|
||||
} else if (Opc == TargetOpcode::INSERT_SUBREG ||
|
||||
Opc == TargetOpcode::SUBREG_TO_REG) {
|
||||
SDValue N0 = Node->getOperand(0);
|
||||
|
60
test/CodeGen/X86/zext-extract_subreg.ll
Normal file
60
test/CodeGen/X86/zext-extract_subreg.ll
Normal file
@ -0,0 +1,60 @@
|
||||
; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s
|
||||
|
||||
define void @t() nounwind ssp {
|
||||
; CHECK: t:
|
||||
entry:
|
||||
br i1 undef, label %return, label %if.end.i
|
||||
|
||||
if.end.i: ; preds = %entry
|
||||
%tmp7.i = load i32* undef, align 4, !tbaa !0
|
||||
br i1 undef, label %return, label %if.end
|
||||
|
||||
if.end: ; preds = %if.end.i
|
||||
; CHECK: %if.end
|
||||
; CHECK: movl (%{{.*}}), [[REG:%[a-z]+]]
|
||||
; CHECK-NOT: movl [[REG]], [[REG]]
|
||||
; CHECK-NEXT: xorb
|
||||
%tmp138 = select i1 undef, i32 0, i32 %tmp7.i
|
||||
%tmp867 = zext i32 %tmp138 to i64
|
||||
br label %while.cond
|
||||
|
||||
while.cond: ; preds = %while.body, %if.end
|
||||
%tmp869 = sub i64 %tmp867, 0
|
||||
%scale2.0 = trunc i64 %tmp869 to i32
|
||||
%cmp149 = icmp eq i32 %scale2.0, 0
|
||||
br i1 %cmp149, label %while.end, label %land.rhs
|
||||
|
||||
land.rhs: ; preds = %while.cond
|
||||
br i1 undef, label %while.body, label %while.end
|
||||
|
||||
while.body: ; preds = %land.rhs
|
||||
br label %while.cond
|
||||
|
||||
while.end: ; preds = %land.rhs, %while.cond
|
||||
br i1 undef, label %cond.false205, label %cond.true190
|
||||
|
||||
cond.true190: ; preds = %while.end
|
||||
br i1 undef, label %cond.false242, label %cond.true225
|
||||
|
||||
cond.false205: ; preds = %while.end
|
||||
unreachable
|
||||
|
||||
cond.true225: ; preds = %cond.true190
|
||||
br i1 undef, label %cond.false280, label %cond.true271
|
||||
|
||||
cond.false242: ; preds = %cond.true190
|
||||
unreachable
|
||||
|
||||
cond.true271: ; preds = %cond.true225
|
||||
unreachable
|
||||
|
||||
cond.false280: ; preds = %cond.true225
|
||||
unreachable
|
||||
|
||||
return: ; preds = %if.end.i, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
!0 = metadata !{metadata !"int", metadata !1}
|
||||
!1 = metadata !{metadata !"omnipotent char", metadata !2}
|
||||
!2 = metadata !{metadata !"Simple C/C++ TBAA", null}
|
Loading…
Reference in New Issue
Block a user