Fix return of reference of simple type from inlined function into non ref argument

This commit is contained in:
drmortalwombat 2024-06-27 19:34:57 +02:00
parent 2fec9f066f
commit cd7567452a
5 changed files with 93 additions and 12 deletions

View File

@ -0,0 +1,77 @@
#include <stdio.h>
#include <assert.h>
struct X
{
char t;
long l;
};
__striped X xs[16];
X xf[16];
char xp;
__noinline long tt(long n)
{
return n;
}
inline auto & tas(void)
{
return xs[xp].l;
}
inline auto & taf(void)
{
return xf[xp].l;
}
long ts(char n)
{
return tt(tas());
}
long tf(char n)
{
return tt(taf());
}
inline auto bas(void)
{
return xs[xp].l;
}
inline auto baf(void)
{
return xs[xp].l;
}
long bs(char n)
{
return tt(bas());
}
long bf(char n)
{
return tt(baf());
}
int main(void)
{
for(char i=0; i<16; i++)
{
xs[i].l = i * i;
xf[i].l = i * i;
}
for(char i=0; i<16; i++)
{
xp = i;
assert(ts(0) == i * i);
assert(tf(0) == i * i);
assert(bs(0) == i * i);
assert(bf(0) == i * i);
}
return 0;
}

View File

@ -3,6 +3,9 @@ rem @echo off
@call :test bitfields.cpp @call :test bitfields.cpp
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :testn autorefreturn.cpp
@if %errorlevel% neq 0 goto :error
@call :testh opp_string.cpp @call :testh opp_string.cpp
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error

View File

@ -3894,8 +3894,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
else if (vr.mType->IsReference() && !(pdec && pdec->mBase->IsReference())) else if (vr.mType->IsReference() && !(pdec && pdec->mBase->IsReference()))
{ {
vr.mReference++; vr.mReference++;
vr = Dereference(proc, texp, block, inlineMapper, vr);
vr.mType = vr.mType->mBase; vr.mType = vr.mType->mBase;
vr = Dereference(proc, texp, block, inlineMapper, vr);
} }
else else
vr = Dereference(proc, texp, block, inlineMapper, vr); vr = Dereference(proc, texp, block, inlineMapper, vr);

View File

@ -15956,7 +15956,7 @@ bool NativeCodeBasicBlock::JoinXYCascade(void)
return changed; return changed;
} }
bool NativeCodeBasicBlock::GlobalLoadStoreForwarding(const NativeCodeInstruction & als, const NativeCodeInstruction & xls, const NativeCodeInstruction & yls) bool NativeCodeBasicBlock::GlobalLoadStoreForwarding(bool zpage, const NativeCodeInstruction & als, const NativeCodeInstruction & xls, const NativeCodeInstruction & yls)
{ {
bool changed = false; bool changed = false;
@ -16010,7 +16010,7 @@ bool NativeCodeBasicBlock::GlobalLoadStoreForwarding(const NativeCodeInstruction
} }
else else
{ {
if ((ins.mMode == ASMIM_ZERO_PAGE || ins.mMode == ASMIM_ABSOLUTE || ins.mMode == ASMIM_ABSOLUTE_X || ins.mMode == ASMIM_ABSOLUTE_Y) && !(ins.mFlags & NCIF_VOLATILE)) if (((zpage && ins.mMode == ASMIM_ZERO_PAGE) || ins.mMode == ASMIM_ABSOLUTE || ins.mMode == ASMIM_ABSOLUTE_X || ins.mMode == ASMIM_ABSOLUTE_Y) && !(ins.mFlags & NCIF_VOLATILE))
mALSIns = ins; mALSIns = ins;
if (mXLSIns.mType != ASMIT_INV && ins.MayBeSameAddress(mXLSIns)) if (mXLSIns.mType != ASMIT_INV && ins.MayBeSameAddress(mXLSIns))
mXLSIns.mType = ASMIT_INV; mXLSIns.mType = ASMIT_INV;
@ -16027,7 +16027,7 @@ bool NativeCodeBasicBlock::GlobalLoadStoreForwarding(const NativeCodeInstruction
ins.mAddress = 0; ins.mAddress = 0;
changed = true; changed = true;
} }
else if ((ins.mMode == ASMIM_ZERO_PAGE || ins.mMode == ASMIM_ABSOLUTE || ins.mMode == ASMIM_ABSOLUTE_X || ins.mMode == ASMIM_ABSOLUTE_Y) && !(ins.mFlags & NCIF_VOLATILE)) else if (((zpage && ins.mMode == ASMIM_ZERO_PAGE) || ins.mMode == ASMIM_ABSOLUTE || ins.mMode == ASMIM_ABSOLUTE_X || ins.mMode == ASMIM_ABSOLUTE_Y) && !(ins.mFlags & NCIF_VOLATILE))
mALSIns = ins; mALSIns = ins;
else else
mALSIns.mType = ASMIT_INV; mALSIns.mType = ASMIT_INV;
@ -16042,7 +16042,7 @@ bool NativeCodeBasicBlock::GlobalLoadStoreForwarding(const NativeCodeInstruction
} }
else else
{ {
if ((ins.mMode == ASMIM_ZERO_PAGE || ins.mMode == ASMIM_ABSOLUTE || ins.mMode == ASMIM_ABSOLUTE_Y) && !(ins.mFlags & NCIF_VOLATILE)) if (((zpage && ins.mMode == ASMIM_ZERO_PAGE) || ins.mMode == ASMIM_ABSOLUTE || ins.mMode == ASMIM_ABSOLUTE_Y) && !(ins.mFlags & NCIF_VOLATILE))
mXLSIns = ins; mXLSIns = ins;
if (mALSIns.mType != ASMIT_INV && ins.MayBeSameAddress(mALSIns)) if (mALSIns.mType != ASMIT_INV && ins.MayBeSameAddress(mALSIns))
mALSIns.mType = ASMIT_INV; mALSIns.mType = ASMIT_INV;
@ -16061,7 +16061,7 @@ bool NativeCodeBasicBlock::GlobalLoadStoreForwarding(const NativeCodeInstruction
} }
else else
{ {
if ((ins.mMode == ASMIM_ZERO_PAGE || ins.mMode == ASMIM_ABSOLUTE || ins.mMode == ASMIM_ABSOLUTE_Y) && !(ins.mFlags & NCIF_VOLATILE)) if (((zpage && ins.mMode == ASMIM_ZERO_PAGE) || ins.mMode == ASMIM_ABSOLUTE || ins.mMode == ASMIM_ABSOLUTE_Y) && !(ins.mFlags & NCIF_VOLATILE))
mXLSIns = ins; mXLSIns = ins;
else else
mXLSIns.mType = ASMIT_INV; mXLSIns.mType = ASMIT_INV;
@ -16081,7 +16081,7 @@ bool NativeCodeBasicBlock::GlobalLoadStoreForwarding(const NativeCodeInstruction
} }
else else
{ {
if ((ins.mMode == ASMIM_ZERO_PAGE || ins.mMode == ASMIM_ABSOLUTE || ins.mMode == ASMIM_ABSOLUTE_X) && !(ins.mFlags & NCIF_VOLATILE)) if (((zpage && ins.mMode == ASMIM_ZERO_PAGE) || ins.mMode == ASMIM_ABSOLUTE || ins.mMode == ASMIM_ABSOLUTE_X) && !(ins.mFlags & NCIF_VOLATILE))
mYLSIns = ins; mYLSIns = ins;
if (mALSIns.mType != ASMIT_INV && ins.MayBeSameAddress(mALSIns)) if (mALSIns.mType != ASMIT_INV && ins.MayBeSameAddress(mALSIns))
mALSIns.mType = ASMIT_INV; mALSIns.mType = ASMIT_INV;
@ -16100,7 +16100,7 @@ bool NativeCodeBasicBlock::GlobalLoadStoreForwarding(const NativeCodeInstruction
} }
else else
{ {
if ((ins.mMode == ASMIM_ZERO_PAGE || ins.mMode == ASMIM_ABSOLUTE || ins.mMode == ASMIM_ABSOLUTE_X) && !(ins.mFlags & NCIF_VOLATILE)) if (((zpage && ins.mMode == ASMIM_ZERO_PAGE) || ins.mMode == ASMIM_ABSOLUTE || ins.mMode == ASMIM_ABSOLUTE_X) && !(ins.mFlags & NCIF_VOLATILE))
mYLSIns = ins; mYLSIns = ins;
else else
mYLSIns.mType = ASMIT_INV; mYLSIns.mType = ASMIT_INV;
@ -16142,9 +16142,9 @@ bool NativeCodeBasicBlock::GlobalLoadStoreForwarding(const NativeCodeInstruction
} }
} }
if (mTrueJump && mTrueJump->GlobalLoadStoreForwarding(mALSIns, mXLSIns, mYLSIns)) if (mTrueJump && mTrueJump->GlobalLoadStoreForwarding(zpage, mALSIns, mXLSIns, mYLSIns))
changed = true; changed = true;
if (mFalseJump && mFalseJump->GlobalLoadStoreForwarding(mALSIns, mXLSIns, mYLSIns)) if (mFalseJump && mFalseJump->GlobalLoadStoreForwarding(zpage, mALSIns, mXLSIns, mYLSIns))
changed = true; changed = true;
} }
@ -50355,7 +50355,8 @@ void NativeCodeProcedure::Optimize(void)
if (step == 12) if (step == 12)
{ {
ResetVisited(); ResetVisited();
if (mEntryBlock->GlobalLoadStoreForwarding(NativeCodeInstruction(), NativeCodeInstruction(), NativeCodeInstruction())) if (mEntryBlock->GlobalLoadStoreForwarding(false, NativeCodeInstruction(), NativeCodeInstruction(), NativeCodeInstruction()) ||
mEntryBlock->GlobalLoadStoreForwarding(true, NativeCodeInstruction(), NativeCodeInstruction(), NativeCodeInstruction()))
{ {
ResetVisited(); ResetVisited();
NativeRegisterDataSet data; NativeRegisterDataSet data;

View File

@ -509,7 +509,7 @@ public:
// Join sequences of TXA, CLC, ADC #xx into INX, TXA sequences if possible // Join sequences of TXA, CLC, ADC #xx into INX, TXA sequences if possible
bool JoinXYCascade(void); bool JoinXYCascade(void);
bool GlobalLoadStoreForwarding(const NativeCodeInstruction & als, const NativeCodeInstruction & xls, const NativeCodeInstruction & yls); bool GlobalLoadStoreForwarding(bool zpage, const NativeCodeInstruction & als, const NativeCodeInstruction & xls, const NativeCodeInstruction & yls);
bool RegisterValueForwarding(void); bool RegisterValueForwarding(void);
bool CanCombineSameXtoY(int start, int end); bool CanCombineSameXtoY(int start, int end);