[llvm] r288897 - [AVR] Allow loading from stack slots where src and dest registers are identical
Dylan McKay via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 7 03:08:56 PST 2016
Author: dylanmckay
Date: Wed Dec 7 05:08:56 2016
New Revision: 288897
URL: http://llvm.org/viewvc/llvm-project?rev=288897&view=rev
Log:
[AVR] Allow loading from stack slots where src and dest registers are identical
Fixes PR 31256
Added:
llvm/trunk/test/CodeGen/AVR/expand-lddw-dst-src-same.mir
Removed:
llvm/trunk/test/CodeGen/AVR/error-srcreg-destreg-same.ll
Modified:
llvm/trunk/lib/Target/AVR/AVR.h
llvm/trunk/lib/Target/AVR/AVRExpandPseudoInsts.cpp
llvm/trunk/lib/Target/AVR/AVRInstrInfo.td
llvm/trunk/lib/Target/AVR/AVRTargetMachine.cpp
Modified: llvm/trunk/lib/Target/AVR/AVR.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/AVR.h?rev=288897&r1=288896&r2=288897&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AVR/AVR.h (original)
+++ llvm/trunk/lib/Target/AVR/AVR.h Wed Dec 7 05:08:56 2016
@@ -30,6 +30,8 @@ FunctionPass *createAVRFrameAnalyzerPass
FunctionPass *createAVRDynAllocaSRPass();
FunctionPass *createAVRBranchSelectionPass();
+void initializeAVRExpandPseudoPass(PassRegistry&);
+
/// Contains the AVR backend.
namespace AVR {
Modified: llvm/trunk/lib/Target/AVR/AVRExpandPseudoInsts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/AVRExpandPseudoInsts.cpp?rev=288897&r1=288896&r2=288897&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AVR/AVRExpandPseudoInsts.cpp (original)
+++ llvm/trunk/lib/Target/AVR/AVRExpandPseudoInsts.cpp Wed Dec 7 05:08:56 2016
@@ -25,6 +25,8 @@
using namespace llvm;
+#define AVR_EXPAND_PSEUDO_NAME "AVR pseudo instruction expansion pass"
+
namespace {
/// Expands "placeholder" instructions marked as pseudo into
@@ -33,13 +35,13 @@ class AVRExpandPseudo : public MachineFu
public:
static char ID;
- AVRExpandPseudo() : MachineFunctionPass(ID) {}
+ AVRExpandPseudo() : MachineFunctionPass(ID) {
+ initializeAVRExpandPseudoPass(*PassRegistry::getPassRegistry());
+ }
bool runOnMachineFunction(MachineFunction &MF) override;
- StringRef getPassName() const override {
- return "AVR pseudo instruction expansion pass";
- }
+ StringRef getPassName() const override { return AVR_EXPAND_PSEUDO_NAME; }
private:
typedef MachineBasicBlock Block;
@@ -653,18 +655,47 @@ bool AVRExpandPseudo::expand<AVR::LDDWRd
TRI->splitReg(DstReg, DstLoReg, DstHiReg);
assert(Imm < 63 && "Offset is out of range");
- assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
+
+ unsigned TmpLoReg = DstLoReg;
+ unsigned TmpHiReg = DstHiReg;
+
+ // HACK: We shouldn't have instances of this instruction
+ // where src==dest because the instruction itself is
+ // marked earlyclobber. We do however get this instruction when
+ // loading from stack slots where the earlyclobber isn't useful.
+ //
+ // In this case, just use a temporary register.
+ if (DstReg == SrcReg) {
+ TmpLoReg = SCRATCH_REGISTER;
+ TmpHiReg = SCRATCH_REGISTER;
+ }
auto MIBLO = buildMI(MBB, MBBI, OpLo)
- .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
+ .addReg(TmpLoReg, RegState::Define | getDeadRegState(DstIsDead))
.addReg(SrcReg)
.addImm(Imm);
+ // Push the low part of the temporary register to the stack.
+ if (TmpLoReg != DstLoReg)
+ buildMI(MBB, MBBI, AVR::PUSHRr)
+ .addReg(AVR::R0);
+
auto MIBHI = buildMI(MBB, MBBI, OpHi)
- .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
+ .addReg(TmpHiReg, RegState::Define | getDeadRegState(DstIsDead))
.addReg(SrcReg, getKillRegState(SrcIsKill))
.addImm(Imm + 1);
+ // If we need to use a temporary register.
+ if (TmpHiReg != DstHiReg) {
+ // Move the hi result from the tmp register to the destination.
+ buildMI(MBB, MBBI, AVR::MOVRdRr)
+ .addReg(DstHiReg).addReg(SCRATCH_REGISTER);
+
+ // Pop the lo result calculated previously and put it into
+ // the lo destination.
+ buildMI(MBB, MBBI, AVR::POPRd).addReg(DstLoReg);
+ }
+
MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
@@ -1424,6 +1455,8 @@ bool AVRExpandPseudo::expandMI(Block &MB
} // end of anonymous namespace
+INITIALIZE_PASS(AVRExpandPseudo, "avr-expand-pseudo",
+ AVR_EXPAND_PSEUDO_NAME, false, false)
namespace llvm {
FunctionPass *createAVRExpandPseudoPass() { return new AVRExpandPseudo(); }
Modified: llvm/trunk/lib/Target/AVR/AVRInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/AVRInstrInfo.td?rev=288897&r1=288896&r2=288897&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AVR/AVRInstrInfo.td (original)
+++ llvm/trunk/lib/Target/AVR/AVRInstrInfo.td Wed Dec 7 05:08:56 2016
@@ -1207,6 +1207,7 @@ Constraints = "$ptrreg = $base_wb, at early
let canFoldAsLoad = 1,
isReMaterializable = 1 in
{
+ let Constraints = "@earlyclobber $reg" in
def LDDRdPtrQ : FSTDLDD<0,
(outs GPR8:$reg),
(ins memri:$memri),
@@ -1227,7 +1228,8 @@ isReMaterializable = 1 in
Requires<[HasSRAM]>;
let mayLoad = 1,
- hasSideEffects = 0 in
+ hasSideEffects = 0,
+ Constraints = "@earlyclobber $dst" in
def LDDWRdYQ : Pseudo<(outs DREGS:$dst),
(ins memri:$memri),
"lddw\t$dst, $memri",
Modified: llvm/trunk/lib/Target/AVR/AVRTargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/AVRTargetMachine.cpp?rev=288897&r1=288896&r2=288897&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AVR/AVRTargetMachine.cpp (original)
+++ llvm/trunk/lib/Target/AVR/AVRTargetMachine.cpp Wed Dec 7 05:08:56 2016
@@ -77,6 +77,9 @@ TargetPassConfig *AVRTargetMachine::crea
extern "C" void LLVMInitializeAVRTarget() {
// Register the target.
RegisterTargetMachine<AVRTargetMachine> X(getTheAVRTarget());
+
+ auto &PR = *PassRegistry::getPassRegistry();
+ initializeAVRExpandPseudoPass(PR);
}
const AVRSubtarget *AVRTargetMachine::getSubtargetImpl() const {
Removed: llvm/trunk/test/CodeGen/AVR/error-srcreg-destreg-same.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AVR/error-srcreg-destreg-same.ll?rev=288896&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AVR/error-srcreg-destreg-same.ll (original)
+++ llvm/trunk/test/CodeGen/AVR/error-srcreg-destreg-same.ll (removed)
@@ -1,56 +0,0 @@
-; RUN: llc < %s -march=avr | FileCheck %s
-; XFAIL: *
-
-; This occurs when compiling Rust libcore.
-;
-; Assertion failed:
-; (DstReg != SrcReg && "SrcReg and DstReg cannot be the same")
-; lib/Target/AVR/AVRExpandPseudoInsts.cpp, line 817
-;
-; https://github.com/avr-llvm/llvm/issues/229
-
-; CHECK-LABEL: rust_eh_personality
-declare void @rust_eh_personality()
-
-; CHECK-LABEL: __udivmoddi4
-define void @__udivmoddi4(i64 %arg, i64 %arg1) personality i32 (...)* bitcast (void ()* @rust_eh_personality to i32 (...)*) {
-entry-block:
- %tmp = lshr i64 %arg, 32
- %tmp2 = trunc i64 %tmp to i32
- %tmp3 = trunc i64 %arg to i32
- %tmp4 = add i64 %arg1, -1
- br label %bb135
-
-bb133.loopexit:
- ret void
-
-bb135:
- %carry.0120 = phi i64 [ 0, %entry-block ], [ %phitmp, %bb135 ]
- %q.sroa.12.1119 = phi i32 [ %tmp3, %entry-block ], [ %q.sroa.12.0.extract.trunc, %bb135 ]
- %q.sroa.0.1118 = phi i32 [ 0, %entry-block ], [ %q.sroa.0.0.extract.trunc, %bb135 ]
- %r.sroa.0.1116 = phi i32 [ %tmp2, %entry-block ], [ undef, %bb135 ]
- %r.sroa.0.0.insert.ext62 = zext i32 %r.sroa.0.1116 to i64
- %r.sroa.0.0.insert.insert64 = or i64 0, %r.sroa.0.0.insert.ext62
- %tmp5 = shl nuw nsw i64 %r.sroa.0.0.insert.ext62, 1
- %q.sroa.12.0.insert.ext101 = zext i32 %q.sroa.12.1119 to i64
- %q.sroa.12.0.insert.shift102 = shl nuw i64 %q.sroa.12.0.insert.ext101, 32
- %q.sroa.0.0.insert.ext87 = zext i32 %q.sroa.0.1118 to i64
- %q.sroa.0.0.insert.insert89 = or i64 %q.sroa.12.0.insert.shift102, %q.sroa.0.0.insert.ext87
- %tmp6 = lshr i64 %q.sroa.12.0.insert.ext101, 31
- %tmp7 = lshr i64 %r.sroa.0.0.insert.insert64, 31
- %tmp8 = shl nuw nsw i64 %q.sroa.0.0.insert.ext87, 1
- %tmp9 = or i64 %tmp8, %carry.0120
- %q.sroa.0.0.extract.trunc = trunc i64 %tmp9 to i32
- %tmp10 = lshr i64 %q.sroa.0.0.insert.insert89, 31
- %q.sroa.12.0.extract.trunc = trunc i64 %tmp10 to i32
- %r.sroa.13.0.insert.shift72 = shl i64 %tmp7, 32
- %.masked114 = and i64 %tmp5, 4294967294
- %r.sroa.0.0.insert.ext57 = or i64 %tmp6, %.masked114
- %r.sroa.0.0.insert.insert59 = or i64 %r.sroa.0.0.insert.ext57, %r.sroa.13.0.insert.shift72
- %tmp11 = sub i64 %tmp4, %r.sroa.0.0.insert.insert59
- %tmp12 = ashr i64 %tmp11, 63
- %phitmp = and i64 %tmp12, 1
- %tmp13 = icmp ult i32 undef, 32
- br i1 %tmp13, label %bb135, label %bb133.loopexit
-}
-
Added: llvm/trunk/test/CodeGen/AVR/expand-lddw-dst-src-same.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AVR/expand-lddw-dst-src-same.mir?rev=288897&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AVR/expand-lddw-dst-src-same.mir (added)
+++ llvm/trunk/test/CodeGen/AVR/expand-lddw-dst-src-same.mir Wed Dec 7 05:08:56 2016
@@ -0,0 +1,33 @@
+# RUN: llc -O0 -run-pass=avr-expand-pseudo %s -o - 2>&1 | FileCheck %s
+
+# This test ensures that the pseudo expander can correctly handle the case
+# where we are expanding a 16-bit LDD instruction where the source and
+# destination registers are the same.
+#
+# The instruction itself is earlyclobber and so ISel will never produce an
+# instruction like this, but the stack slot loading can and will.
+
+--- |
+ target triple = "avr--"
+ define void @test_lddw() {
+ entry:
+ ret void
+ }
+...
+
+---
+name: test_lddw
+registers:
+ - { id: 0, class: _ }
+body: |
+ ; CHECK-LABEL: bb.0.entry
+ bb.0.entry:
+
+ ; CHECK-NEXT: early-clobber %r0 = LDDRdPtrQ %r29r28, 1
+ ; CHECK-NEXT: PUSHRr %r0, implicit-def %sp, implicit %sp
+ ; CHECK-NEXT: early-clobber %r0 = LDDRdPtrQ %r29r28, 2
+ ; CHECK-NEXT: MOVRdRr %r29, %r0
+ ; CHECK-NEXT: POPRd %r28, implicit-def %sp, implicit %sp
+
+ early-clobber %r29r28 = LDDWRdYQ %r29r28, 1
+...
More information about the llvm-commits
mailing list