The 32-bit PowerPC POWER6 memcpy uses the cmpldi insn when it should use a cmplwi. /* Compare the contents of register 'r5' to the value '16' where r5 */ /* holds '12'. */ cmpldi cr1,5,16 This doesn't normally prove to be a problem except when the 'length' parameter to memcpy, held in register r5 is a computed value and the result has the high 32-bits of the register populated with junk due 64-bit operation (in the error case a rlwinm insn),e.g. 0x1007c240 <r_gset+152>: rlwinm r9,r0,0,0,29 0x1007c244 <r_gset+156>: addi r5,r9,16 0x1007c248 <r_gset+160>: bl 0x100dc750 <memcpy@plt> This causes the cmpldi to result in 'greater' than when comparing '12' to '16' which is erroneous. The correction instruction is cmplwi which ignores the high 32-bits or 'r5': cmplwi cr1,5,16 I'll supply a patch and a testcase shortly.
Created attachment 3911 [details] cmpldi-to-cmplwi.diff This is a fix to correct usage of cmpldi to cmplwi in the 32-bit POWER6 mem[cpy|set]. I'll attach a testcase shortly.
I attempted to produce a standalone testcase that would pass the high-word bits of r5 as non-zero to the power6 memcpy but I was unable to get the compiler to cooperate and reproduce the failure that I originally debugged. Regardless, using cmpldi in 32-bit code is erroneous and in this case can cause an overwrite of an array if r5 (length) parameter has bits set in the high-word of the register. Please check-in.
Patch applied to git.