Closed llvmbot closed 11 years ago
Even though this missed the 3.3 release branch, it will be in the powerpc-darwin8 equivalent of release 3.3.
Fixed on trunk under r181449.
Hi David,
Looks to me like the same test will be fine. You'll just have to change the opcodes to cmplw, stw, lwz, etc., and watch out for any other register moves. Hopefully now that you've seen some examples you can extrapolate the checks for the 32-bit case. Should be a good exercise. Contact me if you get hung up on it.
Bill
Done. Committed to my powerpc-darwin8 branch.
https://github.com/fangism/llvm/commit/ d27de53554abf4443ad386ea451991e4ef32f9ae
Let me know if you'd like me to send this to llvm-commits to target svn trunk.
Yes, please do. There is no reason to leave trunk buggy.
Further review comments also welcome.
Hi David,
Looks to me like the same test will be fine. You'll just have to change the opcodes to cmplw, stw, lwz, etc., and watch out for any other register moves. Hopefully now that you've seen some examples you can extrapolate the checks for the 32-bit case. Should be a good exercise. Contact me if you get hung up on it.
Bill
Done. Committed to my powerpc-darwin8 branch.
https://github.com/fangism/llvm/commit/d27de53554abf4443ad386ea451991e4ef32f9ae
Let me know if you'd like me to send this to llvm-commits to target svn trunk.
Further review comments also welcome.
Hi David,
Looks to me like the same test will be fine. You'll just have to change the opcodes to cmplw, stw, lwz, etc., and watch out for any other register moves. Hopefully now that you've seen some examples you can extrapolate the checks for the 32-bit case. Should be a good exercise. Contact me if you get hung up on it.
Bill
Thanks, Bill, that was a tremendous help! I only had to revise under _func1:
; DARWIN: _func1: ; DARWIN: mr ; DARWIN: mr r[[REG1:[0-9]+]], r[[REGA:[0-9]+]] ; DARWIN: mr r[[REG2:[0-9]+]], r[[REGB:[0-9]+]] ; DARWIN: cmpld cr{{[0-9]+}}, r[[REGA]], r[[REGB]] ; DARWIN: std r[[REG1]], -[[OFFSET1:[0-9]+]] ; DARWIN: std r[[REG2]], -[[OFFSET2:[0-9]+]] ; DARWIN: ld r3, -[[OFFSET1]] ; DARWIN: ld r3, -[[OFFSET2]]
And then the test worked.
I also want to test for PPC 32b as well. Can I just re-use the same .ll test? or what changes would you recommend? Here's what the asm looks like:
% /Users/fang/local/src/LLVM-svn/gcc40-cmake-build/bin/./llc -O0 -mtriple=powerpc-apple-darwin8 < /Volumes/Isolde/sources/LLVM-svn/llvm.git/test/CodeGen/PowerPC/anon_aggr-darwin.ll > ! temp-32.s % cat temp-32.s .machine ppc7400 .section TEXT,textcoal_nt,coalesced,pure_instructions .section TEXT,symbol_stub1,symbol_stubs,pure_instructions,16 .section TEXT,text,regular,pure_instructions .globl _func1 .align 4 _func1: ; @func1 .cfi_startproc ; BB#0: ; %entry mr r2, r5 mr r7, r5 mr r8, r6 cmplw cr0, r5, r6 stw r7, -4(r1) ; 4-byte Folded Spill stw r8, -8(r1) ; 4-byte Folded Spill stw r2, -12(r1) ; 4-byte Folded Spill stw r4, -16(r1) ; 4-byte Folded Spill stw r3, -20(r1) ; 4-byte Folded Spill bne cr0, LBB0_2 b LBB0_1 LBB0_1: ; %equal lwz r3, -4(r1) ; 4-byte Folded Reload blr LBB0_2: ; %unequal lwz r3, -8(r1) ; 4-byte Folded Reload blr .cfi_endproc
.globl _func2
.align 4
_func2: ; @func2 .cfi_startproc ; BB#0: ; %entry stw r9, 48(r1) stw r8, 44(r1) stw r7, 40(r1) stw r6, 36(r1) addi r6, r1, 36 lwz r7, 44(r1) mr r8, r5 mr r9, r5 cmplw cr0, r5, r7 stw r4, -4(r1) ; 4-byte Folded Spill stw r8, -8(r1) ; 4-byte Folded Spill stw r9, -12(r1) ; 4-byte Folded Spill stw r6, -16(r1) ; 4-byte Folded Spill stw r7, -20(r1) ; 4-byte Folded Spill stw r3, -24(r1) ; 4-byte Folded Spill bne cr0, LBB1_2 b LBB1_1 LBB1_1: ; %equal lwz r3, -12(r1) ; 4-byte Folded Reload blr LBB1_2: ; %unequal lwz r3, -20(r1) ; 4-byte Folded Reload blr .cfi_endproc
.globl _func3
.align 4
_func3: ; @func3 .cfi_startproc ; BB#0: ; %entry stw r10, 52(r1) stw r9, 48(r1) stw r8, 44(r1) stw r7, 40(r1) stw r6, 36(r1) stw r5, 32(r1) stw r4, 28(r1) stw r3, 24(r1) addi r3, r1, 40 addi r4, r1, 24 lwz r5, 48(r1) lwz r6, 32(r1) cmplw cr0, r6, r5 stw r3, -4(r1) ; 4-byte Folded Spill stw r4, -8(r1) ; 4-byte Folded Spill stw r5, -12(r1) ; 4-byte Folded Spill stw r6, -16(r1) ; 4-byte Folded Spill bne cr0, LBB2_2 b LBB2_1 LBB2_1: ; %equal lwz r3, -16(r1) ; 4-byte Folded Reload blr LBB2_2: ; %unequal lwz r3, -12(r1) ; 4-byte Folded Reload blr .cfi_endproc
.globl _func4
.align 4
_func4: ; @func4 .cfi_startproc ; BB#0: ; %entry lwz r2, 96(r1) addi r3, r1, 100 lwz r4, 92(r1) lwz r5, 88(r1) lwz r6, 108(r1) mr r7, r2 cmplw cr0, r2, r6 stw r2, -4(r1) ; 4-byte Folded Spill stw r3, -8(r1) ; 4-byte Folded Spill stw r4, -12(r1) ; 4-byte Folded Spill stw r5, -16(r1) ; 4-byte Folded Spill stw r6, -20(r1) ; 4-byte Folded Spill stw r7, -24(r1) ; 4-byte Folded Spill bne cr0, LBB3_2 b LBB3_1 LBB3_1: ; %equal lwz r3, -4(r1) ; 4-byte Folded Reload blr LBB3_2: ; %unequal lwz r3, -20(r1) ; 4-byte Folded Reload blr .cfi_endproc
.subsections_via_symbols
David, the Darwin code gen looks fine to me. The checking commands are a little more complicated because Darwin code gen at -O0 is adding a few unnecessary register move instructions, but we can work around that. Since Darwin assembly syntax uses the "r" and "cr" register designations, that changes things slightly as well.
Here's an untested stab at the FileCheck commands. I'm assuming that you add another RUN line to the existing file, and that you use FileCheck -check-prefix=DARWIN %s on that line. This should get you started -- test it out and remove whatever mistakes I tossed in. ;)
; DARWIN: _func1: ; DARWIN: mr ; DARWIN: mr r[[REG1:[0-9]+], r4 ; DARWIN: mr r[[REG2:[0-9]+], r5 ; DARWIN: cmpld cr{{[0-9]+}}, r[[REG1]], r[[REG2]] ; DARWIN: std r[[REG1]], -[[OFFSET1:[0-9]+]] ; DARWIN: std r[[REG2]], -[[OFFSET2:[0-9]+]] ; DARWIN: ld r3, -[[OFFSET1]] ; DARWIN: ld r3, -[[OFFSET2]]
; DARWIN: _func2: ; DARWIN: addi r[[REG1:[0-9]+]], r1, 64 ; DARWIN: ld r[[REG2:[0-9]+]], 8(r[[REG1]]) ; DARWIN: mr ; DARWIN: mr r[[REG3:[0-9]+]], r4 ; DARWIN: cmpld cr{{[0-9]+}}, r4, r[[REG2]] ; DARWIN: std r[[REG3]], -[[OFFSET1:[0-9]+]] ; DARWIN: std r[[REG2]], -[[OFFSET2:[0-9]+]] ; DARWIN: ld r3, -[[OFFSET1]] ; DARWIN: ld r3, -[[OFFSET2]]
; DARWIN: _func3: ; DARWIN: addi r[[REG1:[0-9]+]], r1, 64 ; DARWIN: addi r[[REG2:[0-9]+]], r1, 48 ; DARWIN: ld r[[REG3:[0-9]+]], 8(r[[REG1]]) ; DARWIN: ld r[[REG4:[0-9]+]], 8(r[[REG2]]) ; DARWIN: cmpld cr{{[0-9]+}}, r[[REG4]], r[[REG3]] ; DARWIN: std r[[REG3]], -[[OFFSET1:[0-9]+]] ; DARWIN: std r[[REG4]], -[[OFFSET2:[0-9]+]] ; DARWIN: ld r3, -[[OFFSET2]] ; DARWIN: ld r3, -[[OFFSET1]]
; DARWIN: _func4: ; DARWIN: addi r[[REG1:[0-9]+]], r1, 128 ; DARWIN: ld r[[REG2:[0-9]+]], 120(r1) ; DARWIN: ld r[[REG3:[0-9]+]], 8(r[[REG1]]) ; DARWIN: mr r[[REG4:[0-9]+]], r[[REG2]] ; DARWIN: cmpld cr{{[0-9]+}}, r[[REG2]], r[[REG3]] ; DARWIN: std r[[REG4]], -[[OFFSET1:[0-9]+]] ; DARWIN: std r[[REG3]], -[[OFFSET2:[0-9]+]] ; DARWIN: ld r3, -[[OFFSET1]] ; DARWIN: ld r3, -[[OFFSET2]]
Good luck!
Yes, I'll look at this when I get into the office later today.
Here's the PPC asm I get from Kai's test case, anon_aggr.ll: I'm trying 64b PPC first.
; RUN: llc -O0 -mtriple=powerpc64-apple-darwin8 < %s | FileCheck %s
.machine ppc64
.section __TEXT,__textcoal_nt,coalesced,pure_instructions
.section __TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16
.section __TEXT,__text,regular,pure_instructions
.globl _func1
.align 4
_func1: ; @func1 .cfi_startproc ; BB#0: ; %entry mr r2, r4 mr r6, r4 mr r7, r5 cmpld cr0, r4, r5 std r6, -8(r1) ; 8-byte Folded Spill std r7, -16(r1) ; 8-byte Folded Spill std r2, -24(r1) ; 8-byte Folded Spill std r3, -32(r1) ; 8-byte Folded Spill bne cr0, LBB0_2 b LBB0_1 LBB0_1: ; %equal ld r3, -8(r1) ; 8-byte Folded Reload blr LBB0_2: ; %unequal ld r3, -16(r1) ; 8-byte Folded Reload blr .cfi_endproc
.globl _func2
.align 4
_func2: ; @func2 .cfi_startproc ; BB#0: ; %entry std r6, 72(r1) std r5, 64(r1) addi r5, r1, 64 ld r5, 8(r5) mr r6, r4 mr r2, r4 cmpld cr0, r4, r5 std r6, -8(r1) ; 8-byte Folded Spill std r2, -16(r1) ; 8-byte Folded Spill std r5, -24(r1) ; 8-byte Folded Spill std r3, -32(r1) ; 8-byte Folded Spill bne cr0, LBB1_2 b LBB1_1 LBB1_1: ; %equal ld r3, -16(r1) ; 8-byte Folded Reload blr LBB1_2: ; %unequal ld r3, -24(r1) ; 8-byte Folded Reload blr .cfi_endproc
.globl _func3
.align 4
_func3: ; @func3 .cfi_startproc ; BB#0: ; %entry std r6, 72(r1) std r5, 64(r1) std r4, 56(r1) std r3, 48(r1) addi r3, r1, 64 addi r4, r1, 48 ld r3, 8(r3) ld r4, 8(r4) cmpld cr0, r4, r3 std r3, -8(r1) ; 8-byte Folded Spill std r4, -16(r1) ; 8-byte Folded Spill bne cr0, LBB2_2 b LBB2_1 LBB2_1: ; %equal ld r3, -16(r1) ; 8-byte Folded Reload blr LBB2_2: ; %unequal ld r3, -8(r1) ; 8-byte Folded Reload blr .cfi_endproc
.globl _func4
.align 4
_func4: ; @func4 .cfi_startproc ; BB#0: ; %entry addi r2, r1, 128 ld r3, 120(r1) ld r4, 112(r1) ld r2, 8(r2) mr r5, r3 cmpld cr0, r3, r2 std r4, -8(r1) ; 8-byte Folded Spill std r5, -16(r1) ; 8-byte Folded Spill std r2, -24(r1) ; 8-byte Folded Spill bne cr0, LBB3_2 b LBB3_1 LBB3_1: ; %equal ld r3, -16(r1) ; 8-byte Folded Reload blr LBB3_2: ; %unequal ld r3, -24(r1) ; 8-byte Folded Reload blr .cfi_endproc
.subsections_via_symbols
Does this look reasonable?
I don't have any experience writing the CHECK statements for tests, but I tried to mimic the format in anon_aggr.ll, but am having trouble matching up registers across lines. There are too many register moves to easily match lines. COuld someone help me review the asm output above for Darwin PPC, and perhaps help me convert it into CHECK statements for a FileCheck test?
That's excellent news! I confess I'm surprised that this occurs on the IR you recorded here. I don't see any of the multi-type anonymous aggregates passed as parameters that characterized the problem shown by the D compiler. There must be another way for the argument counting mismatch to occur. I'd have to guess that the struct.F hiding a varargs is to blame here.
BTW, I fixed the problem (using Kai's patch) for 64-bit SVR4, but did not attempt to fix the Darwin code, as I didn't feel competent to make changes to Darwin ABI code, and since the D compiler was not being targeted to Darwin. Instead I added the FIXME you see there in case the problem arises for Darwin in the future.
Re-applying the part of Kai's patch that was withdrawn for Darwin seems to have fixed this test case! I will try out Kai's test case(s) as well.
BTW, I fixed the problem (using Kai's patch) for 64-bit SVR4, but did not attempt to fix the Darwin code, as I didn't feel competent to make changes to Darwin ABI code, and since the D compiler was not being targeted to Darwin. Instead I added the FIXME you see there in case the problem arises for Darwin in the future.
I added the comment in question. This was for the other bug that was fixed under 14779 (Kai Nacke). The compiler for the D language generated arguments in a form that does not occur with Clang, creating anonymous aggregates with multiple types. (Clang creates a new type for an aggregate with multiple types, thus reducing it to a single type, so there was no mismatch in walking the arguments with Clang-generated IR.) Since this is Clang output, that specific issue is probably not involved, but I'm sure the grotty FuncArg code could be wrong somewhere...
(gdb) call Ptr->dump() 0x23ab7e0: i32 = FrameIndex<-1>
MachinePointerInfo(FuncArg, CurArgOffset) is somehow invalid, it looks like this is because FuncArg does not point to a valid object. Maybe this has something to do with the FIXME at the top of the loop: // FIXME: FuncArg and Ins[ArgNo] must reference the same argument. // When passing anonymous aggregates, this is currently not true. // See LowerFormalArguments_64SVR4 for a fix. Function::const_arg_iterator FuncArg = MF.getFunction()->arg_begin(); for (unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo, ++FuncArg) {
This is unfamiliar territory to me. If the patch is obvious to you, could you post it, or describe it a bit more explicitly? I'm happy to test and report back.
Can you use svn blame and see who wrote the comment (it was not me). Then add that person to this bug.
(gdb) call Ptr->dump() 0x23ab7e0: i32 = FrameIndex<-1>
MachinePointerInfo(FuncArg, CurArgOffset) is somehow invalid, it looks like this is because FuncArg does not point to a valid object. Maybe this has something to do with the FIXME at the top of the loop: // FIXME: FuncArg and Ins[ArgNo] must reference the same argument. // When passing anonymous aggregates, this is currently not true. // See LowerFormalArguments_64SVR4 for a fix. Function::const_arg_iterator FuncArg = MF.getFunction()->arg_begin(); for (unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo, ++FuncArg) {
This is unfamiliar territory to me. If the patch is obvious to you, could you post it, or describe it a bit more explicitly? I'm happy to test and report back.
| | | | | | : PtrInfo.V->Type: (0): void
As the assertion mentions, that's wrong...
So the problem seems to be this (in LowerFormalArguments_Darwin): 2654 SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT); 2655 EVT ObjType = ObjSize == 1 ? MVT::i8 : MVT::i16; 2656 SDValue Store = DAG.getTruncStore(Val.getValue(1), dl, Val, FIN, 2657 MachinePointerInfo(FuncArg, 2658 CurArgOffset), 2659 ObjType, false, false, 0);
(gdb) call Ptr->dump() 0x23ab7e0: i32 = FrameIndex<-1>
MachinePointerInfo(FuncArg, CurArgOffset) is somehow invalid, it looks like this is because FuncArg does not point to a valid object. Maybe this has something to do with the FIXME at the top of the loop: // FIXME: FuncArg and Ins[ArgNo] must reference the same argument. // When passing anonymous aggregates, this is currently not true. // See LowerFormalArguments_64SVR4 for a fix. Function::const_arg_iterator FuncArg = MF.getFunction()->arg_begin(); for (unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo, ++FuncArg) {
more detail:
... | | | | | : FuncArg iteration 3 | | | | | : ObjSize = 4 | | | | | : CurArgOffset = 36 | | | | | : MinReservedArea = 40 | | | | | : Flags.isByVal() | | | | | : ObjSize = 1 | | | | | : ArgSize = 4 | | | | | : CurArgOffset = 39 | | | | | : GPR_idx = 3 | | | | | : Num_GPR_Regs = 8 | | | | | -{ unsigned int llvm::MachineFunction::addLiveIn(unsigned int, const llvm::TargetRegisterClass) | | | | | | -{ unsigned int llvm::MachineRegisterInfo::getLiveInVirtReg(unsigned int) const | | | | | | /-} unsigned int llvm::MachineRegisterInfo::getLiveInVirtReg(unsigned int) const | | | | | | : VReg (LiveIn) = 0 | | | | | | -{ unsigned int llvm::MachineRegisterInfo::createVirtualRegister(const llvm::TargetRegisterClass) | | | | | | | : NumVirtRegs = 3 | | | | | | | : Reg = 2147483651 | | | | | | /-} unsigned int llvm::MachineRegisterInfo::createVirtualRegister(const llvm::TargetRegisterClass) | | | | | | : VReg (createVirtual) = 2147483651 | | | | | /-} unsigned int llvm::MachineFunction::addLiveIn(unsigned int, const llvm::TargetRegisterClass) | | | | | : VReg = 2147483651 | | | | | -{ llvm::SDValue llvm::SelectionDAG::getNode(unsigned int, llvm::DebugLoc, llvm::SDVTList, const llvm::SDValue, unsigned int) | | | | | /-} llvm::SDValue llvm::SelectionDAG::getNode(unsigned int, llvm::DebugLoc, llvm::SDVTList, const llvm::SDValue, unsigned int) | | | | | : Val: 0x75848060: i32,ch = CopyFromReg 0x75513cfc: ch = EntryToken, 0x75847868: i32 = Register %vreg3 | | | | | : FIN: 0x75847c20: i32 = FrameIndex<-1> | | | | | -{ llvm::SDValue llvm::SelectionDAG::getTruncStore(llvm::SDValue, llvm::DebugLoc, llvm::SDValue, llvm::SDValue, llvm::MachinePointerInfo, llvm::EVT, bool, bool, unsigned int, const llvm::MDNode) | | | | | | : isVolatile? 0 | | | | | | : isNonTemporal? 0 | | | | | | : Alignment 0 | | | | | | : Chain: 0x75848060: i32,ch = CopyFromReg 0x75513cfc: ch = EntryToken, 0x75847868: i32 = Register %vreg3 | | | | | | : Val: 0x75848060: i32,ch = CopyFromReg 0x75513cfc: ch = EntryToken, 0x75847868: i32 = Register %vreg3 | | | | | | : Ptr: 0x75847c20: i32 = FrameIndex<-1> | | | | | | : PtrInfo.V @0x0x7550bb54 | | | | | | : PtrInfo.V @0x0x7550bb54 | | | | | | : PtrInfo.V->Type: (0): void %"u\80C\F8\00\00\00\00uP\A6\A0\00\00\00\00uP\BBLuP\BD\F0uP\BF\1CuP\BB0\00\00\00\00\00\00\00\03\00\00\00\00uP\B9\C0\00\00\00\00\00\00\00\00u\81\DC\10,\00\00\00uP\BC\B0uP\BC\B4uP\BC\B4uP\BC\90uP\BC\90uP\BC\A0\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\0EuP\BC\0C\00\00\00\12\FF\FF\FF\FFlessuP\BB0\00\00\00\00\00\00\00\00\00\1D\00\0CuP\B2`\00\00\00\00uP\B2nuP\B9\8C\00\00\00\00uP\B9\99uP\BC\0C\00\00\00\00uP\BC\1B\1FL%\F8\0D\00\00\00u\81\DE\90uP\B2\E0\00\00\00\00uP\BC\C0\00\00\00\03\FF\FF\FF\FFuP\BFPuP\A6\A0\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00uP\BF\00uP\C0\00uP\C0\A0\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\02\02\81\03\90e}\01\07a\F92\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00AdX\03wN\A9\08m\EF\89\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00uP=UuPE\10uP\BD\A4uP\BD\B4uP\BD\C4\00\00\00\03uP\BE\80\FF\FF\FF\FFuP\ACP\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\04\00\00\00\ ... more garbage ...
Anything look obviously wrong?
More trace details leading up to garbage PtrInfo.V:
| | | | | : FuncArg iteration 3 | | | | | : ObjSize = 4 | | | | | : MinReservedArea = 40 | | | | | : Flags.isByVal() | | | | | : ObjSize = 1 | | | | | : ArgSize = 4 | | | | | : CurArgOffset = 39 | | | | | : GPR_idx = 3 | | | | | : Num_GPR_Regs = 8 | | | | | -{ unsigned int llvm::MachineFunction::addLiveIn(unsigned int, const llvm::TargetRegisterClass) | | | | | | -{ unsigned int llvm::MachineRegisterInfo::getLiveInVirtReg(unsigned int) const | | | | | | /-} unsigned int llvm::MachineRegisterInfo::getLiveInVirtReg(unsigned int) const | | | | | | : VReg (LiveIn) = 0 | | | | | | -{ unsigned int llvm::MachineRegisterInfo::createVirtualRegister(const llvm::TargetRegisterClass) | | | | | | | : NumVirtRegs = 3 | | | | | | | : Reg = 2147483651 | | | | | | /-} unsigned int llvm::MachineRegisterInfo::createVirtualRegister(const llvm::TargetRegisterClass) | | | | | | : VReg (createVirtual) = 2147483651 | | | | | /-} unsigned int llvm::MachineFunction::addLiveIn(unsigned int, const llvm::TargetRegisterClass) | | | | | : VReg = 2147483651 | | | | | -{ llvm::SDValue llvm::SelectionDAG::getTruncStore(llvm::SDValue, llvm::DebugLoc, llvm::SDValue, llvm::SDValue, llvm::MachinePointerInfo, llvm::EVT, bool, bool, unsigned int, const llvm::MDNode) | | | | | | : isVolatile? 0 | | | | | | : isNonTemporal? 0 | | | | | | : Alignment 0 | | | | | | : Chain: 0x75848060: i32,ch = CopyFromReg 0x75513cfc, 0x75847868 | | | | | | : Val: 0x75848060: i32,ch = CopyFromReg 0x75513cfc, 0x75847868 | | | | | | : Ptr: 0x75847c20: i32 = FrameIndex<-1> | | | | | | : PtrInfo.V @0x0x7550bb54 | | | | | | : PtrInfo.V @0x0x7550bb54 | | | | | | : PtrInfo.V->Type: (0): void | | | | | | -{ llvm::MachineMemOperand llvm::MachineFunction::getMachineMemOperand(llvm::MachinePointerInfo, unsigned int, uint64_t, unsigned int, const llvm::MDNode, const llvm::MDNode) | | | | | | | -{ llvm::MachineMemOperand::MachineMemOperand(llvm::MachinePointerInfo, unsigned int, uint64_t, unsigned int, const llvm::MDNode, const llvm::MDNode) | | | | | | | | : f = 2 | | | | | | | | : s = 1 | | | | | | | | : a = 1 | | | | | | | | : PtrInfo.V -> %"u\80C\F8\00\00\00\00uP\A6\A0\00\00\00\00uP\BBLuP\BD\F0uP\BF\1CuP\BB0\00\00\00\00\00\00\00\03\00\00\00\00uP\B9\C0\00\00\00\00\00\00\00\00u\81\DC\10,\00\00\00uP\BC\B0uP\BC\B4uP\BC\B4uP\BC\90uP\BC\90uP\BC\A0\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\0EuP\BC\0C\00\00\00\12\FF\FF\FF\FFlessuP\BB0\00\00\00\00\00\00\00\00\00\1D\00\0CuP\B2`\00\00\00\00uP\B2nuP\B9\8C\00\00\00\00uP\B9\99uP\BC\0C\00\00\00\00uP\BC\1B\1FH\D5\F8\0D\00\00\00u\81\DE\90uP\B2\E0\00\00\00\00uP\BC\C0\00\00\00\03\FF\FF\FF\FFuP\BFPuP\A6\A0\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00uP\BF\00uP\C0\00uP\C0\A0\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\02\02\81\03\90e}*\01\07a\F92\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00AdX\03wN\A9\08m\EF\89\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00uP=UuPE\10uP\BD\A4uP\BD\B4uP\BD\C4\
/// createVirtualRegister - Create and return a new virtual register in the /// function with the specified register class. /// unsigned MachineRegisterInfo::createVirtualRegister(const TargetRegisterClass *RegClass){ STACKTRACE_VERBOSE; assert(RegClass && "Cannot create register without RegClass!"); assert(RegClass->isAllocatable() && "Virtual register RegClass must be allocatable.");
// New virtual register number. STACKTRACE_INDENT_PRINT("NumVirtRegs = " << getNumVirtRegs() << endl); unsigned Reg = TargetRegisterInfo::index2VirtReg(getNumVirtRegs()); STACKTRACE_INDENT_PRINT("Reg = " << Reg << endl); VRegInfo.grow(Reg); VRegInfo[Reg].first = RegClass; RegAllocHints.grow(Reg); return Reg; }
Those VReg values may not be garbage after all; it seems to be a convention for virtual register numbers. include/llvm/Target/TargetRegisterInfo.h: /// index2VirtReg - Convert a 0-based index to a virtual register number. /// This is the inverse operation of VirtReg2IndexFunctor below. static unsigned index2VirtReg(unsigned Index) { return Index | (1u << 31); }
| | | | -{ llvm::SDValue llvm::PPCTargetLowering::LowerFormalArguments_Darwin(llvm::SDValue, llvm::CallingConv::ID, bool, const llvm::SmallVectorImpl
llvm::MachineRegisterInfo::createVirtualRegister() seems to return a garbage value...
produced from -S -emit-llvm % cat SetTheory.ll ; ModuleID = 'SetTheory.cpp' target datalayout = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v128:128:128-n32" target triple = "powerpc-apple-macosx10.4.0"
%class.C = type { i8 } %struct.F = type { %struct.D } %struct.D = type { i32 (...)** } %class.B = type { i8 }
@_ZTV1F = linkonce_odr unnamed_addr constant [3 x i8] [i8 null, i8 bitcast ({ i8, i8, i8 } @_ZTI1F to i8), i8 bitcast (void (%struct.F, i64, %class.B) @_ZN1F6apply2Ex1B to i8)] @_ZTVN10cxxabiv120si_class_type_infoE = external global i8 @_ZTS1F = linkonce_odr constant [3 x i8] c"1F\00" @_ZTI1D = external constant i8 @_ZTI1F = linkonce_odr unnamed_addr constant { i8, i8, i8 } { i8 bitcast (i8 getelementptr inbounds (i8 @_ZTVN10cxxabiv120si_class_type_infoE, i32 2) to i8), i8 getelementptr inbounds ([3 x i8] @_ZTS1F, i32 0, i32 0), i8* bitcast (i8* @_ZTI1D to i8) } @_ZTV1D = external unnamed_addr constant [3 x i8*]
define void @_ZN1CC1Ev(%class.C %this) unnamed_addr #0 align 2 { entry: %this.addr = alloca %class.C, align 4 store %class.C %this, %class.C %this.addr, align 4 %this1 = load %class.C %this.addr call void @_ZN1CC2Ev(%class.C %this1) ret void }
; Function Attrs: nounwind define void @_ZN1CC2Ev(%class.C %this) unnamed_addr #1 align 2 { entry: %this.addr = alloca %class.C, align 4 %agg.tmp.ensured = alloca %struct.F, align 4 store %class.C %this, %class.C %this.addr, align 4 %this1 = load %class.C %this.addr %0 = bitcast %struct.F %agg.tmp.ensured to i8 call void @llvm.memset.p0i8.i32(i8 %0, i8 0, i32 4, i32 4, i1 false) call void @_ZN1FC1Ev(%struct.F* %agg.tmp.ensured) #2 ret void }
; Function Attrs: nounwind declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) #2
; Function Attrs: inlinehint nounwind define linkonce_odr void @_ZN1FC1Ev(%struct.F %this) unnamed_addr #3 align 2 { entry: %this.addr = alloca %struct.F, align 4 store %struct.F %this, %struct.F %this.addr, align 4 %this1 = load %struct.F %this.addr call void @_ZN1FC2Ev(%struct.F %this1) #2 ret void }
; Function Attrs: inlinehint nounwind define linkonce_odr void @_ZN1FC2Ev(%struct.F %this) unnamed_addr #3 align 2 { entry: %this.addr = alloca %struct.F, align 4 store %struct.F %this, %struct.F %this.addr, align 4 %this1 = load %struct.F %this.addr %0 = bitcast %struct.F %this1 to %struct.D call void @_ZN1DC2Ev(%struct.D %0) #2 %1 = bitcast %struct.F* %this1 to i8* store i8* getelementptr inbounds ([3 x i8] @_ZTV1F, i64 0, i64 2), i8 %1 ret void }
; Function Attrs: inlinehint nounwind define linkonce_odr void @_ZN1DC2Ev(%struct.D %this) unnamed_addr #3 align 2 { entry: %this.addr = alloca %struct.D, align 4 store %struct.D %this, %struct.D %this.addr, align 4 %this1 = load %struct.D %this.addr %0 = bitcast %struct.D %this1 to i8* store i8* getelementptr inbounds ([3 x i8] @_ZTV1D, i64 0, i64 2), i8 %0 ret void }
; Function Attrs: nounwind define linkonce_odr void @_ZN1F6apply2Ex1B(%struct.F %this, i64, %class.B byval) unnamed_addr #1 align 2 { entry: %this.addr = alloca %struct.F, align 4 %.addr = alloca i64, align 8 store %struct.F %this, %struct.F* %this.addr, align 4 store i64 %0, i64 %.addr, align 8 %this1 = load %struct.F** %this.addr ret void }
attributes #0 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #2 = { nounwind } attributes #3 = { inlinehint nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
So it is crashing in llvm::PPCInstrInfo::storeRegToStackSlot?
Can you use -emit-llvm and extract an .ll test case; I can look at it here as well.
In the trace, it already returned from storeTRegToStackSlot(). The highest caller shown there was llvm::SelectionDAGISel::runOnMachineFunction().
Here are some more local variable dumps:
...
| | | | -{ llvm::SDValue llvm::PPCTargetLowering::LowerFormalArguments_Darwin(llvm::SDValue, llvm::CallingConv::ID, bool, const llvm::SmallVectorImpl
When I see a value like VReg = 2147483651, I usually raise() an eyebrow.
I'll provide a -emit-llvm in a sec...
So it is crashing in llvm::PPCInstrInfo::storeRegToStackSlot?
Can you use -emit-llvm and extract an .ll test case; I can look at it here as well.
Here's a stack trace dump. Does this narrow down where the problem might be?
-{ virtual void llvm::PPCInstrInfo::storeRegToStackSlot(llvm::MachineBasicBlock&, llvm::MachineBasicBlock::bundle_iterator<llvm::MachineInstr, llvm::ilist_iterator
"LowerFormalArguments_Darwin" looks like it could be Darwin-specific. :)
Fair enough.
More data points (the following targets succeed): % ../../../gcc40-cmake-build/bin/clang++ -c SetTheory.cpp -target powerpc-linux-gnu -S -o SetTheory.s % ../../../gcc40-cmake-build/bin/clang++ -c SetTheory.cpp -target powerpc-linux-gnu -S -fPIC -o SetTheory.s % ../../../gcc40-cmake-build/bin/clang++ -c SetTheory.cpp -target powerpc-unknown-freebsd -S -o SetTheory.s % ../../../gcc40-cmake-build/bin/clang++ -c SetTheory.cpp -target powerpc-unknown-freebsd -S -fPIC -o SetTheory.s
The reduced test case compiles to asm just fine when targeting powerpc-linux-gnu and powerpc-unknown-freebsd, even with -fPIC.
Right, it is likely Darwin specific -- and still can't be a release blocker ;)
Fair enough.
More data points (the following targets succeed): % ../../../gcc40-cmake-build/bin/clang++ -c SetTheory.cpp -target powerpc-linux-gnu -S -o SetTheory.s % ../../../gcc40-cmake-build/bin/clang++ -c SetTheory.cpp -target powerpc-linux-gnu -S -fPIC -o SetTheory.s % ../../../gcc40-cmake-build/bin/clang++ -c SetTheory.cpp -target powerpc-unknown-freebsd -S -o SetTheory.s % ../../../gcc40-cmake-build/bin/clang++ -c SetTheory.cpp -target powerpc-unknown-freebsd -S -fPIC -o SetTheory.s
The reduced test case compiles to asm just fine when targeting powerpc-linux-gnu and powerpc-unknown-freebsd, even with -fPIC.
Bumping importance, this prevents me from building powerpc-darwin8 stage-2, even with optimizations off.
powerpc-darwin8 is not a supported platform, and so no bugs that affect only it can be release blockers. "tier 1" platforms are, among other things, only x86 and ARM based.
Bumping importance, this prevents me from building powerpc-darwin8 stage-2, even with optimizations off.
Further reduced test case:
% cat SetTheory.cpp class B {}; class C { public: C(); }; struct D { virtual void apply2(long long, B ) ; }; struct F : D { void apply2(long long, B ) { } }; C::C() { F(); }
% ../../../gcc40-cmake-build/bin/clang++ -c SetTheory.cpp -o SetTheory.o
/Users/fang/local/src/LLVM-svn/llvm/lib/CodeGen/MachineInstr.cpp:428: failed assertion `(PtrInfo.V == 0 || isa
PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT: Preprocessed source(s) and associated run script(s) are located at: clang-3.1: note: diagnostic msg: /tmp/SetTheory-EQFFqm.cpp clang-3.1: note: diagnostic msg: /tmp/SetTheory-EQFFqm.sh clang-3.1: note: diagnostic msg:
Also fails with: -arch ppc64 (but on a different code path)
Does NOT fail with: -arch i386 -arch x86_64
Extended Description
Report separated from bug 14779.
% ../../../gcc40-cmake-build/bin/clang++ -c SetTheory.cpp -o SetTheory.o /Users/fang/local/src/LLVM-svn/llvm/lib/CodeGen/MachineInstr.cpp:428: failed assertion `(PtrInfo.V == 0 || isa(PtrInfo.V->getType())) && "invalid pointer value"'
Stack dump:
PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT: Preprocessed source(s) and associated run script(s) are located at: clang-3.1: note: diagnostic msg: /tmp/SetTheory-af7r6O.cpp clang-3.1: note: diagnostic msg: /tmp/SetTheory-af7r6O.sh clang-3.1: note: diagnostic msg:
Reduced test case from Konstantin in bug 14779: % cat SetTheory.cpp class A; class B {}; class C { public: typedef A RecSet; C(); }; struct D { virtual void apply2(C &p1, int , C::RecSet &p3, long long , C::RecSet &p5, B ) ; }; struct F : D { void apply2(C &p1, int , C::RecSet &p3, long long, C::RecSet &p5, B ) { } }; C::C() { F(); }
This occurs on the powerpc-darwin8 branch (last trunk merge r179582).