From cd7567452adac824800ceaf2d92f6adfdb4b0592 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Thu, 27 Jun 2024 19:34:57 +0200 Subject: [PATCH] Fix return of reference of simple type from inlined function into non ref argument --- autotest/autorefreturn.cpp | 77 +++++++++++++++++++++++++++++++++ autotest/autotest.bat | 3 ++ oscar64/InterCodeGenerator.cpp | 2 +- oscar64/NativeCodeGenerator.cpp | 21 ++++----- oscar64/NativeCodeGenerator.h | 2 +- 5 files changed, 93 insertions(+), 12 deletions(-) create mode 100644 autotest/autorefreturn.cpp diff --git a/autotest/autorefreturn.cpp b/autotest/autorefreturn.cpp new file mode 100644 index 0000000..85ef370 --- /dev/null +++ b/autotest/autorefreturn.cpp @@ -0,0 +1,77 @@ +#include +#include + +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; +} diff --git a/autotest/autotest.bat b/autotest/autotest.bat index 29d507f..278ff93 100644 --- a/autotest/autotest.bat +++ b/autotest/autotest.bat @@ -3,6 +3,9 @@ rem @echo off @call :test bitfields.cpp @if %errorlevel% neq 0 goto :error +@call :testn autorefreturn.cpp +@if %errorlevel% neq 0 goto :error + @call :testh opp_string.cpp @if %errorlevel% neq 0 goto :error diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 2978ce6..a350188 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -3894,8 +3894,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* else if (vr.mType->IsReference() && !(pdec && pdec->mBase->IsReference())) { vr.mReference++; - vr = Dereference(proc, texp, block, inlineMapper, vr); vr.mType = vr.mType->mBase; + vr = Dereference(proc, texp, block, inlineMapper, vr); } else vr = Dereference(proc, texp, block, inlineMapper, vr); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index d0acdc3..ee43e9e 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -15956,7 +15956,7 @@ bool NativeCodeBasicBlock::JoinXYCascade(void) 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; @@ -16010,7 +16010,7 @@ bool NativeCodeBasicBlock::GlobalLoadStoreForwarding(const NativeCodeInstruction } 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; if (mXLSIns.mType != ASMIT_INV && ins.MayBeSameAddress(mXLSIns)) mXLSIns.mType = ASMIT_INV; @@ -16027,7 +16027,7 @@ bool NativeCodeBasicBlock::GlobalLoadStoreForwarding(const NativeCodeInstruction ins.mAddress = 0; 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; else mALSIns.mType = ASMIT_INV; @@ -16042,7 +16042,7 @@ bool NativeCodeBasicBlock::GlobalLoadStoreForwarding(const NativeCodeInstruction } 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; if (mALSIns.mType != ASMIT_INV && ins.MayBeSameAddress(mALSIns)) mALSIns.mType = ASMIT_INV; @@ -16061,7 +16061,7 @@ bool NativeCodeBasicBlock::GlobalLoadStoreForwarding(const NativeCodeInstruction } 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; else mXLSIns.mType = ASMIT_INV; @@ -16081,7 +16081,7 @@ bool NativeCodeBasicBlock::GlobalLoadStoreForwarding(const NativeCodeInstruction } 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; if (mALSIns.mType != ASMIT_INV && ins.MayBeSameAddress(mALSIns)) mALSIns.mType = ASMIT_INV; @@ -16100,7 +16100,7 @@ bool NativeCodeBasicBlock::GlobalLoadStoreForwarding(const NativeCodeInstruction } 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; else 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; - if (mFalseJump && mFalseJump->GlobalLoadStoreForwarding(mALSIns, mXLSIns, mYLSIns)) + if (mFalseJump && mFalseJump->GlobalLoadStoreForwarding(zpage, mALSIns, mXLSIns, mYLSIns)) changed = true; } @@ -50355,7 +50355,8 @@ void NativeCodeProcedure::Optimize(void) if (step == 12) { ResetVisited(); - if (mEntryBlock->GlobalLoadStoreForwarding(NativeCodeInstruction(), NativeCodeInstruction(), NativeCodeInstruction())) + if (mEntryBlock->GlobalLoadStoreForwarding(false, NativeCodeInstruction(), NativeCodeInstruction(), NativeCodeInstruction()) || + mEntryBlock->GlobalLoadStoreForwarding(true, NativeCodeInstruction(), NativeCodeInstruction(), NativeCodeInstruction())) { ResetVisited(); NativeRegisterDataSet data; diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index 8a6e2c0..78f728b 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -509,7 +509,7 @@ public: // Join sequences of TXA, CLC, ADC #xx into INX, TXA sequences if possible 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 CanCombineSameXtoY(int start, int end);