Closed llvmbot closed 14 years ago
Ah, I thought aliasing would be enough (it was before), ok. Thanks Evan!
Nevermind, it's implicitly defining %D0(1) but using %F0. So that's correctly. The bug is in SparcRegisterInfo.td:
def D0 : Rd< 0, "F0", [F0, F1]>, DwarfRegNum<32>;
This states D0 aliases F0, F1 but does not specify F0 and F1 as sub-registers of D0. I'll fix this.
I know. That's not the problem. SparcGenInstrInfo.inc also looks alright. This is CALL's implicit defs:
static const unsigned ImplicitList3[] = { SP::O0, SP::O1, SP::O2, SP::O3, SP::O4, SP::O5, SP::O7, SP::G1, SP::G2, SP::G3, SP::G4, SP::G5, SP::G6, SP::G7, SP::D0, SP::D1, SP::D2, SP:\:D3, SP::D4, SP::D5, SP::D6, SP::D7, SP::D8, SP::D9, SP::D10, SP::D11, SP::D12, SP::D13, SP::D14, SP::D15, 0 };
Looks ok. But when ScheduleDAG creates the MI, it's getting an incorrectly list of implicit defs.
Ugh, funness. Check this out:
def D0 : Rd< 0, "F0", [F0, F1]>, DwarfRegNum<32>; def D1 : Rd< 2, "F2", [F2, F3]>, DwarfRegNum<34>;
Note that the D0 register prints as "F0".
Strangeness:
12 CALL
%mreg(76)
%mreg(51)
%mreg(56)
%mreg(11)
%mreg(7)
%mreg(76) %mreg(77) %mreg(78)
16 %reg1025 = FMOVS %F0
According to this CALL implicitly defines %F0(1), but the FMOVS uses %F0(17) (aka %D0 which consists of both %F0 and %F1). That messes live interval up. But SparcInstrInfo.td defines CALL as this:
let Uses = [O0, O1, O2, O3, O4, O5], hasDelaySlot = 1, isCall = 1, noResults = 1, Defs = [O0, O1, O2, O3, O4, O5, O7, G1, G2, G3, G4, G5, G6, G7, D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in { def CALL : InstSP<(ops calltarget:$dst), "call $dst", []> { bits<30> disp; let op = 1; let Inst{29-0} = disp; }
So CALL should implicitly define %F0(17) instead of %F0(1). What is going on?
Here is a simple reduced testcase for llvm/llvm-bugzilla-archive#1540 :
declare float @sinf(float)
declare double @sin(double)
define double @test_sin(float %F) {
%G = call float @sinf( float %F ) ;
$ llvm-as < t.ll | llc -march=sparc
If this is a sparc backend bug, let me know and I'll be happy to fix it.
-Chris
Bug llvm/llvm-bugzilla-archive#1550 has been marked as a duplicate of this bug.
This appears to be a liveness bug of some sort. When I run: $ llc attachment.cgi -march=sparc -f -print-machineinstrs -debug | & less
I see:
144 CALL
If F0 is dead at 144, it can't be killed at 148. Evan, thoughts?
Of interest, the Sparc CALL instruction is marked as clobbering D0, which is aliased to F0/F1. Perhaps this is part of the problem?
-Chris
Confirmed with current SVN.
llc: /home/nicholas/llvm-commit/include/llvm/CodeGen/LiveIntervalAnalysis.h:102: llvm::LiveInterval& llvm::LiveIntervals::getInterval(unsigned int): Assertion `I != r2iMap_.end() && "Interval does not exist for register"' failed.
Program received signal SIGABRT, Aborted. [Switching to Thread -137754928 (LWP 1290)] 0xffffe405 in __kernel_vsyscall () (gdb) bt
at /home/nicholas/llvm-commit/include/llvm/CodeGen/LiveIntervalAnalysis.h:102
CopyMI=0x8a80e00, SrcReg=17, DstReg=1048, PhysOnly=false)
at SimpleRegisterCoalescing.cpp:220
this=0x8a7e4a8, MBB=0x8a7f428, TryAgain=0xffc3116c, PhysOnly=false)
at SimpleRegisterCoalescing.cpp:799
this=0x8a7e4a8) at SimpleRegisterCoalescing.cpp:816
this=0x8a7e4a8, fn=@0x8a7ef20) at SimpleRegisterCoalescing.cpp:1042
F=@0x8a790c0)
at /home/nicholas/llvm-commit/include/llvm/CodeGen/MachineFunctionPass.h:41
F=@0x8a790c0) at PassManager.cpp:1140
F=@0x8a790c0) at PassManager.cpp:1098
F=@0x8a790c0) at PassManager.cpp:1043
Extended Description
I have tried to compile LLVM bytecode for the SPEC CPU2000 benchmark bzip2 to SPARC assembly in a cross-compiler setting (LLVM running on x86_64). I am using llvm-2.0 as distributed in a tar-ball from llvm.org.
Bugpoint reduced the error to this case: ; ModuleID = 'bugpoint-reduced-simplified.bc' target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64" target triple = "x86_64-unknown-linux-gnu" @seedi = external global i64 ; <i64*> [#uses=1]
define i32 @spec_random_load(i32 %fd) { entry: br i1 false, label %bb, label %bb69
bb: ; preds = %entry br i1 false, label %cond_true12, label %bb56
cond_true12: ; preds = %bb %tmp21 = load i64 @seedi ; [#uses=1]
%tmp24 = srem i64 %tmp21, 127773 ; [#uses=1]
%tmp26 = mul i64 %tmp24, 16807 ; [#uses=1]
%tmp29 = sub i64 %tmp26, 0 ; [#uses=1]
%storemerge = add i64 0, %tmp29 ; [#uses=1]
%tmp3940 = sitofp i64 %storemerge to float ; [#uses=1]
%tmp41 = mul float %tmp3940, 0x3E00000000000000 ; [#uses=1]
%tmp4142 = fpext float %tmp41 to double ; [#uses=1]
%tmp47 = mul double %tmp4142, 2.560000e+02 ; [#uses=1]
%tmp4748 = fptosi double %tmp47 to i32 ; [#uses=1]
%tmp474849 = trunc i32 %tmp4748 to i8 ; [#uses=1]
store i8 %tmp474849, i8 null
ret i32 0
bb56: ; preds = %bb ret i32 0
bb69: ; preds = %entry ret i32 0 }
the command: llc -march=sparc -f -o bzip2.s bugpoint-reduced-function.bc
crashes: llc: /.../llvm/llvm-2.0/include/llvm/CodeGen/LiveIntervalAnalysis.h:121: llvm::LiveInterval& llvm::LiveIntervals::getInterval(unsigned int): Assertion `I != r2iMap_.end() && "Interval does not exist for register"' failed.
Some analysis shows that the error occurs in expanded floating-point bytecodes.