From a6b6269a38c4be8163080accb0aa2dfcf2158ed8 Mon Sep 17 00:00:00 2001 From: metagn Date: Tue, 17 Sep 2024 03:49:33 +0300 Subject: [PATCH 1/3] make distinct conversions addressable in VM fixes #24097 --- compiler/vmgen.nim | 32 ++++++++++++++++++++++---------- tests/vm/tconvaddr.nim | 16 ++++++++++++++++ 2 files changed, 38 insertions(+), 10 deletions(-) create mode 100644 tests/vm/tconvaddr.nim diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 20249ae734ee..eb149b945dea 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -696,6 +696,11 @@ proc genAsgnPatch(c: PCtx; le: PNode, value: TRegister) = let dest = c.genx(le, {gfNodeAddr}) c.gABC(le, opcWrDeref, dest, 0, value) c.freeTemp(dest) + of nkHiddenStdConv, nkHiddenSubConv, nkConv: + if sameBackendType(le.typ, le[1].typ): + let dest = c.genx(le[1], {gfNodeAddr}) + c.gABC(le, opcWrDeref, dest, 0, value) + c.freeTemp(dest) else: discard @@ -868,7 +873,7 @@ proc genAddSubInt(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) = genBinaryABC(c, n, dest, opc) c.genNarrow(n, dest) -proc genConv(c: PCtx; n, arg: PNode; dest: var TDest; opc=opcConv) = +proc genConv(c: PCtx; n, arg: PNode; dest: var TDest, flags: TGenFlags = {}; opc=opcConv) = let t2 = n.typ.skipTypes({tyDistinct}) let targ2 = arg.typ.skipTypes({tyDistinct}) @@ -882,7 +887,7 @@ proc genConv(c: PCtx; n, arg: PNode; dest: var TDest; opc=opcConv) = result = false if implicitConv(): - gen(c, arg, dest) + gen(c, arg, dest, flags) return let tmp = c.genx(arg) @@ -1050,7 +1055,7 @@ proc whichAsgnOpc(n: PNode; requiresCopy = true): TOpcode = else: (if requiresCopy: opcAsgnComplex else: opcFastAsgnComplex) -proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) = +proc genMagic(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}, m: TMagic) = case m of mAnd: c.genAndOr(n, opcFJmp, dest) of mOr: c.genAndOr(n, opcTJmp, dest) @@ -1189,7 +1194,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) = if t.kind in {tyUInt8..tyUInt32} or (t.kind == tyUInt and size < 8): c.gABC(n, opcNarrowU, dest, TRegister(size*8)) of mCharToStr, mBoolToStr, mCStrToStr, mStrToStr, mEnumToStr: - genConv(c, n, n[1], dest) + genConv(c, n, n[1], dest, flags) of mEqStr: genBinaryABC(c, n, dest, opcEqStr) of mEqCString: genBinaryABC(c, n, dest, opcEqCString) of mLeStr: genBinaryABC(c, n, dest, opcLeStr) @@ -1652,6 +1657,13 @@ proc genAsgn(c: PCtx; le, ri: PNode; requiresCopy: bool) = c.freeTemp(cc) else: gen(c, ri, dest) + of nkHiddenStdConv, nkHiddenSubConv, nkConv: + if sameBackendType(le.typ, le[1].typ): + let dest = c.genx(le[1], {gfNode}) + let tmp = c.genx(ri) + c.preventFalseAlias(le, opcWrDeref, dest, 0, tmp) + c.freeTemp(dest) + c.freeTemp(tmp) else: let dest = c.genx(le, {gfNodeAddr}) genAsgn(c, dest, ri, requiresCopy) @@ -2164,7 +2176,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) = if n[0].kind == nkSym: let s = n[0].sym if s.magic != mNone: - genMagic(c, n, dest, s.magic) + genMagic(c, n, dest, flags, s.magic) elif s.kind == skMethod: localError(c.config, n.info, "cannot call method " & s.name.s & " at compile time") @@ -2221,11 +2233,11 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) = unused(c, n, dest) gen(c, n[0]) of nkHiddenStdConv, nkHiddenSubConv, nkConv: - genConv(c, n, n[1], dest) + genConv(c, n, n[1], dest, flags) of nkObjDownConv: - genConv(c, n, n[0], dest) + genConv(c, n, n[0], dest, flags) of nkObjUpConv: - genConv(c, n, n[0], dest) + genConv(c, n, n[0], dest, flags) of nkVarSection, nkLetSection: unused(c, n, dest) genVarSection(c, n) @@ -2235,7 +2247,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) = genLit(c, newSymNode(n[namePos].sym), dest) of nkChckRangeF, nkChckRange64, nkChckRange: if skipTypes(n.typ, abstractVar).kind in {tyUInt..tyUInt64}: - genConv(c, n, n[0], dest) + genConv(c, n, n[0], dest, flags) else: let tmp0 = c.genx(n[0]) @@ -2261,7 +2273,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) = of nkPar, nkClosure, nkTupleConstr: genTupleConstr(c, n, dest) of nkCast: if allowCast in c.features: - genConv(c, n, n[1], dest, opcCast) + genConv(c, n, n[1], dest, flags, opcCast) else: genCastIntFloat(c, n, dest) of nkTypeOfExpr: diff --git a/tests/vm/tconvaddr.nim b/tests/vm/tconvaddr.nim new file mode 100644 index 000000000000..72accc8623ee --- /dev/null +++ b/tests/vm/tconvaddr.nim @@ -0,0 +1,16 @@ +block: # issue #24097 + type Foo = distinct int + proc foo(x: var Foo) = + int(x) += 1 + proc bar(x: var int) = + x += 1 + static: + var x = Foo(1) + int(x) = int(x) + 1 + doAssert x.int == 2 + int(x) += 1 + doAssert x.int == 3 + foo(x) + doAssert x.int == 4 + bar(int(x)) # need vmgen flags propagated for this + doAssert x.int == 5 From 99e2f26f4ffb284485f9705c47628304e9c1a957 Mon Sep 17 00:00:00 2001 From: metagn Date: Tue, 17 Sep 2024 03:53:34 +0300 Subject: [PATCH 2/3] more tests --- tests/vm/tconvaddr.nim | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/vm/tconvaddr.nim b/tests/vm/tconvaddr.nim index 72accc8623ee..cea6c7632221 100644 --- a/tests/vm/tconvaddr.nim +++ b/tests/vm/tconvaddr.nim @@ -14,3 +14,25 @@ block: # issue #24097 doAssert x.int == 4 bar(int(x)) # need vmgen flags propagated for this doAssert x.int == 5 + type Bar = object + x: Foo + static: + var obj = Bar(x: Foo(1)) + int(obj.x) = int(obj.x) + 1 + doAssert obj.x.int == 2 + int(obj.x) += 1 + doAssert obj.x.int == 3 + foo(obj.x) + doAssert obj.x.int == 4 + bar(int(obj.x)) # need vmgen flags propagated for this + doAssert obj.x.int == 5 + static: + var arr = @[Foo(1)] + int(arr[0]) = int(arr[0]) + 1 + doAssert arr[0].int == 2 + int(arr[0]) += 1 + doAssert arr[0].int == 3 + foo(arr[0]) + doAssert arr[0].int == 4 + bar(int(arr[0])) # need vmgen flags propagated for this + doAssert arr[0].int == 5 From f3fd24703273ffbaa7720bd0c31f832ccd7a484c Mon Sep 17 00:00:00 2001 From: metagn Date: Tue, 17 Sep 2024 03:58:25 +0300 Subject: [PATCH 3/3] just recurse, fixes result etc --- compiler/vmgen.nim | 10 ++-------- tests/vm/tconvaddr.nim | 11 +++++++++++ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index eb149b945dea..182e3752240a 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -698,9 +698,7 @@ proc genAsgnPatch(c: PCtx; le: PNode, value: TRegister) = c.freeTemp(dest) of nkHiddenStdConv, nkHiddenSubConv, nkConv: if sameBackendType(le.typ, le[1].typ): - let dest = c.genx(le[1], {gfNodeAddr}) - c.gABC(le, opcWrDeref, dest, 0, value) - c.freeTemp(dest) + genAsgnPatch(c, le[1], value) else: discard @@ -1659,11 +1657,7 @@ proc genAsgn(c: PCtx; le, ri: PNode; requiresCopy: bool) = gen(c, ri, dest) of nkHiddenStdConv, nkHiddenSubConv, nkConv: if sameBackendType(le.typ, le[1].typ): - let dest = c.genx(le[1], {gfNode}) - let tmp = c.genx(ri) - c.preventFalseAlias(le, opcWrDeref, dest, 0, tmp) - c.freeTemp(dest) - c.freeTemp(tmp) + genAsgn(c, le[1], ri, requiresCopy) else: let dest = c.genx(le, {gfNodeAddr}) genAsgn(c, dest, ri, requiresCopy) diff --git a/tests/vm/tconvaddr.nim b/tests/vm/tconvaddr.nim index cea6c7632221..9762a9e591e2 100644 --- a/tests/vm/tconvaddr.nim +++ b/tests/vm/tconvaddr.nim @@ -36,3 +36,14 @@ block: # issue #24097 doAssert arr[0].int == 4 bar(int(arr[0])) # need vmgen flags propagated for this doAssert arr[0].int == 5 + proc testResult(): Foo = + result = Foo(1) + int(result) = int(result) + 1 + doAssert result.int == 2 + int(result) += 1 + doAssert result.int == 3 + foo(result) + doAssert result.int == 4 + bar(int(result)) # need vmgen flags propagated for this + doAssert result.int == 5 + doAssert testResult().int == 5