Date: Sat, 20 Feb 2016 01:02:56 -0800 From: Mark Millard <markmi@dsl-only.net> To: Roman Divacky <rdivacky@vlakno.cz> Cc: FreeBSD Toolchain <freebsd-toolchain@freebsd.org>, FreeBSD PowerPC ML <freebsd-ppc@freebsd.org> Subject: Re: I've submitted 207175 for a clang 3.8.0 va_list handling problem for powerpc [fpr use also tested] Message-ID: <601B33C1-D258-4F23-9814-1B4291C57A5F@dsl-only.net> In-Reply-To: <20160220083450.GA55777@vlakno.cz> References: <D7D536A4-68B6-4506-BDFB-8C2C41E1C958@dsl-only.net> <20160215191100.GA17387@vlakno.cz> <3A260EC5-E69A-4980-8F74-C04395F4E5F4@dsl-only.net> <20160215201800.GA20796@vlakno.cz> <D702187C-6B8C-42AC-855D-45A570FDB0FA@dsl-only.net> <D3351840-02B5-4696-8163-D90A6E039E4C@dsl-only.net> <74577A87-3006-43A9-9EAB-F51D946B6245@dsl-only.net> <28FF474D-2109-4605-8B2B-C5374CBCCF42@dsl-only.net> <8EB46124-3335-4643-8C64-16DA56D481F5@dsl-only.net> <8C40A5D7-C0B8-4142-89D4-228017C446CE@dsl-only.net> <20160220083450.GA55777@vlakno.cz>
next in thread | previous in thread | raw e-mail | index | archive | help
Thanks! llvm bugzilla's 26605 did not having anything yet for this so I've = copied over your note. But I've left the status alone. The next thing that I ran into looks nastier: c++'s exception handling = is broken. #include <exception> int main(void) { try { throw std::exception(); } catch (std::exception& e) {} // same result without & return 0; } does not work on powerpc (SEGV) or powerpc64 (unbounded loop, never = returning from _Unwind_RaiseException). (The powerpc64 context is using = devel/powerpc64-gcc or g++49 as the compiler with the system's headers = and libraries. powerpc64-gcc was used for buildworld/buildkernel as well = for this context.) [g++49 using its own headers and libraries works fine for the above = program.] =3D=3D=3D Mark Millard markmi at dsl-only.net On 2016-Feb-20, at 12:34 AM, Roman Divacky <rdivacky@vlakno.cz> wrote: Fwiw, I've just committed the patch to clang in r261422. You might want to keep using a local modification or ask dim@ to import that patch to our copy of 3.8. Thanks for your diagnosis and testing! Roman On Thu, Feb 18, 2016 at 02:29:29PM -0800, Mark Millard wrote: > On 2016-Feb-17, at 9:23 PM, Mark Millard <markmi@dsl-only.net> wrote: >>=20 >> My fpr related notes/worries about the fix were wrong. >>=20 >> I finally got some time to look at this again and I see that I = somehow missed the following code when I looked before: >>=20 >> // The calling convention either uses 1-2 GPRs or 1 FPR. >> Address NumRegsAddr =3D Address::invalid(); >> if (isInt || IsSoftFloatABI) { >> NumRegsAddr =3D Builder.CreateStructGEP(VAList, 0, = CharUnits::Zero(), "gpr"); >> } else { >> NumRegsAddr =3D Builder.CreateStructGEP(VAList, 1, = CharUnits::One(), "fpr"); >> } >>=20 >> So the >>=20 >> Builder.CreateStore(Builder.getInt8(8), NumRegsAddr); >>=20 >> in Case 2 is tracking gpr vs. fpr usage contexts as it should. Also: >>=20 >> llvm::Value *NumRegs =3D Builder.CreateLoad(NumRegsAddr, = "numUsedRegs"); >>=20 >> // "Align" the register count when TY is i64. >> if (isI64 || (isF64 && IsSoftFloatABI)) { >> NumRegs =3D Builder.CreateAdd(NumRegs, Builder.getInt8(1)); >> NumRegs =3D Builder.CreateAnd(NumRegs, Builder.getInt8((uint8_t) = ~1U)); >> } >>=20 >> llvm::Value *CC =3D >> Builder.CreateICmpULT(NumRegs, Builder.getInt8(8), "cond"); >>=20 >> is using the same bounds check figure (8) for gpr and fpr. >>=20 >> Apparently that common bound is one reason that the clang numbering = is not the same as the ABI document's numbering: clang's numbering = allows using the same figure for both contexts. (Given the prior = alignment for isI64 (or isF64 with IsSoftFloatABI).) >>=20 >> Sorry for the prior noise about fpr. >>=20 >> It is still true that DOUBLE_OR_FLOAT is untested so far. >>=20 >> =3D=3D=3D >> Mark Millard >> markmi at dsl-only.net >=20 > I finally got some time to apply to some basic testing involving = double as well (for involving fpr use). . . >=20 > No problems with exceptions. Looking at the memory contents at various = stages in gdb looks good. va_list's gpr, fpr, overflow_arg_area changes = as its va_args use progresses look good. Values extracted by va_args use = looks good. Both default and -O2. >=20 > The added >=20 >> Builder.CreateStore(Builder.getInt8(8), NumRegsAddr); >=20 >=20 > passes my checks. I've not observed any problems from buildworld = materials, unlike when that line is missing. >=20 > [Note: I run with the signal delivery modified to have a "red zone" to = deal with other aspects of clang 3.8.0 code generation that are not ABI = compliant for when the stack pointer is moved. Having a "red zone" is = still operationally correct for an ABI compliant code generation, it = just temporarily wastes more bytes. Also: the kernel was built with gcc = 4.2.1 but world was built with clang 3.8.0.] >=20 >=20 > =3D=3D=3D > Mark Millard > markmi at dsl-only.net >=20 > . . . [bad fpr related material omitted] . . . >=20 > On 2016-Feb-16, at 2:45 AM, Mark Millard <markmi@dsl-only.net> wrote: >=20 > I used: >=20 >> Index: /usr/src/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> --- /usr/src/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp = (revision 295601) >> +++ /usr/src/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp = (working copy) >> @@ -3569,6 +3569,8 @@ >> { >> CGF.EmitBlock(UsingOverflow); >>=20 >> + Builder.CreateStore(Builder.getInt8(8), NumRegsAddr); >> + >> // Everything in the overflow area is rounded up to a size of at = least 4. >> CharUnits OverflowAreaAlign =3D CharUnits::fromQuantity(4); >=20 > as my test change. (Get evidence of operation before potential cleanup = of the duplicated 8's.) >=20 > After a full buildworld/installworld based on the updated compiler. . = . >=20 > My simple example of the problem no longer fails. >=20 > "ls -l -n /" now works. >=20 > "svnlite update -r295601 /usr/src" now works. >=20 > So whatever you want to do for the details of any submitted code, the = basics of the change do avoid the SEGVs and allow these programs to = work. >=20 >=20 > =3D=3D=3D > Mark Millard > markmi at dsl-only.net >=20 > On 2016-Feb-15, at 4:27 PM, Mark Millard <markmi@dsl-only.net> wrote: >=20 > On 2016-Feb-15, at 1:20 PM, Mark Millard <markmi at dsl-only.net> = wrote: >>=20 >> On 2016-Feb-15, at 12:18 PM, Roman Divacky <rdivacky at vlakno.cz> = wrote: >>>=20 >>> On Mon, Feb 15, 2016 at 12:17:50PM -0800, Mark Millard wrote: >>>> On 2016-Feb-15, at 11:11 AM, Roman Divacky <rdivacky at vlakno.cz> = wrote: >>>>>=20 >>>>> Mark, I believe you're right. What do you think about this patch? >>>>>=20 >>>>> Index: tools/clang/lib/CodeGen/TargetInfo.cpp >>>>> = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >>>>> --- tools/clang/lib/CodeGen/TargetInfo.cpp (revision = 260852) >>>>> +++ tools/clang/lib/CodeGen/TargetInfo.cpp (working copy) >>>>> @@ -3599,6 +3599,8 @@ >>>>> { >>>>> CGF.EmitBlock(UsingOverflow); >>>>>=20 >>>>> + Builder.CreateStore(Builder.getInt8(11), NumRegsAddr); >>>>> + >>>>> // Everything in the overflow area is rounded up to a size of at = least 4. >>>>> CharUnits OverflowAreaAlign =3D CharUnits::fromQuantity(4); >>>>>=20 >>>>>=20 >>>>> Can you test it? >>>>=20 >>>> It may be later today before I can start the the test process. >>>>=20 >>>> While your change is not wrong as presented, it does seem to be = based on the ABI document's numbering with the range 3 <=3D gr <12, = where 3 <=3D gr < 11 cover r3-r10 use and gr=3D11 implies overflow stack = area use. (gr being the ABI documents name.) >>>>=20 >>>> The clang code generation that I saw while analyzing the problem = and the clang source that you had me look at did not use that numbering. = Instead it seems to be based on 0 <=3D gpr < 9, where 0 <=3D gpr < 8 = cover r3-r10 use and gpr=3D8 implies overflow stack area use. (gpr being = what gdb showed me as I remember.) In other words: clang counts the = number of "parameter registers" already in use as it goes along instead = of tracking register numbers that have been used. >>>>=20 >>>> So assigning any value that appears to be positive and >=3D 8 = should work, such as: >>>>=20 >>>> Builder.CreateStore(Builder.getInt8(8), NumRegsAddr); >>>=20 >>> Can you check what number gcc uses? We want to be interoperable with = gcc. >>>=20 >>> Anyway, thanks for testing! >>>=20 >>> Roman >>=20 >> I'll do that check of gcc 4.2.1 code generation before starting the = test later today. >>=20 >> But if the clang numbering is different in gcc 4.2.1 then far more = than just adding a >>=20 >>> Builder.CreateStore(Builder.getInt8(?), NumRegsAddr) >>=20 >>=20 >> for some "?" would need to be involved in the changes in order to = reach compatibility. >>=20 >>=20 >> I'll note that for clang 3.8.0 the actual comparison instruction = generated is of the form >>=20 >>> cmplwi r?,7 >>=20 >>=20 >> for some r?, such as r5 or r4, and the conditional branch generated = is a bgt instruction. >>=20 >> =3D=3D=3D >> Mark Millard >> markmi at dsl-only.net >=20 > gcc 4.2.1 generates comparison instructions for va_arg of the form: >=20 > cmplwi cr7,r0,8 >=20 > and the conditional branch generated is a "bge cr7, . . ." = instruction. >=20 > So the same number range is in use by both compilers: They are = compatible for the bounds checks for reg vs. overflow for how they = count, equality inclusion/exclusion matching up with the specific number = (8 vs. 7) used to make things the same overall. >=20 > Other aspects of the code generation distinctions would take me time = to analyze. It will be a while before I will be looking at other points. >=20 >=20 > =3D=3D=3D > Mark Millard > markmi at dsl-only.net >=20 >=20 >=20 >=20 >=20 >=20 > _______________________________________________ > freebsd-toolchain@freebsd.org mailing list > https://lists.freebsd.org/mailman/listinfo/freebsd-toolchain > To unsubscribe, send any mail to = "freebsd-toolchain-unsubscribe@freebsd.org"
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?601B33C1-D258-4F23-9814-1B4291C57A5F>