Ticket #446 (Fixed)Tue Jan 16 18:05:38 UTC 2018
cc 5.75: compiler fails to mark R12 as containing pertinant data and reuses R12 for different subexpression results
Reported by: | André Timmermans (100) | Severity: | Major |
Part: | RISC OS: C/C++ toolchain | Release: | |
Milestone: | Status | Fixed |
Details by André Timmermans (100):
Here is a minimal case:
<pre>
<code>
typedef struct CRect
{
int x0;
int y0;
int x1;
int y1;
} CRect;
typedef struct CSize
{
int cx;
int cy;
} CSize;
typedef struct WListCore WListCore;
struct WListCore
{
CSize m_Size;
CSize m_Offset;
unsigned int m_flags;
};
#define EWList_RightToLeft 0×00000040
#define EWList_BottomToTop 0×00000080
CRect WListCore_RowColsToPixels(const WListCore* This, const CRect* pbox)
{
CRect box;
if (This->m_flags & EWList_RightToLeft)
{
box.×0 = This>m_Offset.cx – pbox->x1 * This->m_Size.cx;
box.×1 = This>m_Offset.cx – pbox->x0 * This->m_Size.cx;
}
else
{
box.×0 = This->m_Offset.cx + pbox->x0 * This->m_Size.cx;
box.×1 = This->m_Offset.cx + pbox->x1 * This->m_Size.cx;
}
if (This->m_flags & EWList_BottomToTop)
{
box.y0 = This->m_Offset.cy + pbox->y0 * This->m_Size.cy;
box.y1 = This->m_Offset.cy + pbox->y1 * This->m_Size.cy;
}
else
{
box.y0 = This>m_Offset.cy – pbox->y1 * This->m_Size.cy;
box.y1 = This>m_Offset.cy pbox>y0 * This->m_Size.cy;
}
return box;
}
</code>
</pre>
Just drop it on !cc and compile it.
The generated output which I somewhat commented is as follow:
<pre>
<code>
STMDB R13!,{R4-R6,R14}
LDR R5,[R1,#16] ; R5 = This->m_flags
LDR R12,[R1,#8] ; R12 = This->m_Offset.cx
LDR R6,[R2,#8] ; R6 = pbox->x1
LDR R3,[R1,#0] ; R3 = This->m_Size.cx
TST R5,#&40 ; if (This->m_flags & EWList_RightToLeft)
RSBNE R12,R12,#0 ; R12 = This>m_Offset.cx
MULNE R12,R3,R6 ; R12 = pbox->x1 * This->m_Size.cx !!! R12 !!!
LDR R14,[R2,#0] ; R14 = pbox->x0
SUBNE R4,R12,R12 ; R4 = 0 !!!
MULNE R12,R3,R14 ; R12 = pbox->x0 * This->m_Size.cx !!! R12 !!!
MLAEQ R4,R3,R14,R12
SUBNE R12,R12,R12
LDR R14,[R2,#12]
MLAEQ R12,R3,R6,R12
TST R5,#&80
LDR R5,[R1,#4]
LDR R1,[R1,#12]
MOV R3,R12
MULEQ R12,R5,R14
LDR R2,[R2,#4]
RSBEQ R1,R1,#0
SUBEQ R12,R1,R12
MLANE R12,R5,R2,R1
MLANE R1,R5,R14,R1
MULEQ R12,R5,R2
STMIA R0!,{R4,R12}
SUBEQ R1,R1,R12
STR R3,[R0],#4
STR R1,[R0,#0]
LDMIA R13!,{R4-R6,PC}
</code>
</pre>
As you can see at several occasions it stores results into R12 when it should use an extra register.
Changelog:
Modified by André Timmermans (100) Tue, January 16 2018 - 18:12:45 GMT
Forgot to mention this issue is not present on cc 5.72
Modified by Sprow (202) Wed, March 28 2018 - 21:31:48 GMT
- Status changed from Open to Fixed
Assuming I recovered the hyphens that the markup engine wrote (best to attach source files!) it seems fine in cc 5.76:
; generated by Norcroft RISC OS ARM C vsn 5.76 [19 Mar 2018]
AREA |C$$code|, CODE, READONLYx$codeseg |
WListCore_RowColsToPixels
STMDB sp!,{v1,v2,v6,lr}
LDR v1,[a2,#&10]
LDR ip,[a3,#8]
LDR v2,[a3]
LDR a4,[a2]
TST v1,#&40
MOVNE v6,ip
MULNE v6,a4,v6
LDR lr,[a2,#8]
MULNE ip,a4,v2
SUBNE v6,lr,v6
MLAEQ v6,a4,v2,lr
SUBNE ip,lr,ip
MLAEQ ip,a4,ip,lr
TST v1,#&80
LDR v1,[a3,#&c]
LDR lr,[a2,#4]
LDR a3,[a3,#4]
LDR a2,[a2,#&c]
MULEQ v2,lr,v1
MOV a4,ip
STR v6,[a1],#4
MULEQ ip,lr,a3
SUBEQ v2,a2,v2
MLANE v2,lr,a3,a2
SUBEQ a2,a2,ip
MLANE a2,lr,v1,a2
STR v2,[a1],#4
STR a4,[a1],#4
STR a2,[a1]
LDMIA sp!,{v1,v2,v6,pc}
x$dataseg |