Skip to content

Commit a363d26

Browse files
committed
fix(kmir): handle noop drop-glue calls
1 parent eb770d6 commit a363d26

6 files changed

Lines changed: 147 additions & 2 deletions

File tree

kmir/src/kmir/kdist/mir-semantics/kmir.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,17 @@ where the returned result should go.
363363
requires isIntrinsicFunction(FUNC)
364364
andBool #functionNameMatchesEnv(getFunctionName(FUNC))
365365
366+
syntax Bool ::= isNoOpFunction(MonoItemKind) [function]
367+
rule isNoOpFunction(monoItemFn(symbol(""), _, noBody)) => true
368+
rule isNoOpFunction(_) => false [owise]
369+
370+
// SMIR marks some semantically empty shims (e.g. drop glue for trivially droppable slices)
371+
// as NoOpSym. They have no body and should continue immediately without switching frames.
372+
rule [termCallNoOp]:
373+
<k> #execTerminatorCall(_, monoItemFn(symbol(""), _, noBody), _ARGS, _DEST, TARGET, _UNWIND, _SPAN) ~> _
374+
=> #continueAt(TARGET)
375+
</k>
376+
366377
// Regular function call - full state switching and stack setup
367378
rule [termCallFunction]:
368379
<k> #execTerminatorCall(FTY, FUNC, ARGS, DEST, TARGET, UNWIND, SPAN) ~> _
@@ -379,6 +390,7 @@ where the returned result should go.
379390
</currentFrame>
380391
<stack> STACK => ListItem(StackFrame(OLDCALLER, OLDDEST, OLDTARGET, OLDUNWIND, LOCALS)) STACK </stack>
381392
requires notBool isIntrinsicFunction(FUNC)
393+
andBool notBool isNoOpFunction(FUNC)
382394
andBool notBool #functionNameMatchesEnv(getFunctionName(FUNC))
383395
384396
// Function call to a function in the break-on set - same as termCallFunction but separate rule id for cut-point
@@ -397,6 +409,7 @@ where the returned result should go.
397409
</currentFrame>
398410
<stack> STACK => ListItem(StackFrame(OLDCALLER, OLDDEST, OLDTARGET, OLDUNWIND, LOCALS)) STACK </stack>
399411
requires notBool isIntrinsicFunction(FUNC)
412+
andBool notBool isNoOpFunction(FUNC)
400413
andBool #functionNameMatchesEnv(getFunctionName(FUNC))
401414
402415
syntax Bool ::= isIntrinsicFunction(MonoItemKind) [function]

kmir/src/kmir/kdist/mir-semantics/rt/data.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,15 @@ The following rule resolves this situation by using the head element.
508508
)
509509
=> #traverseProjection(DEST, VALUE, projectionElemField(IDX, TY) PROJS, CTXTS) ... </k> // TODO mark context?
510510
[preserves-definedness, priority(100)]
511+
512+
rule <k> #traverseProjection(
513+
DEST,
514+
Range(ListItem(Union(_, _) #as VALUE) _REST:List),
515+
projectionElemField(IDX, TY) PROJS,
516+
CTXTS
517+
)
518+
=> #traverseProjection(DEST, VALUE, projectionElemField(IDX, TY) PROJS, CTXTS) ... </k> // TODO mark context?
519+
[preserves-definedness, priority(100)]
511520
```
512521

513522
#### Unions
@@ -649,6 +658,23 @@ Similar to `ConstantIndex`, the slice _end_ index may count from the _end_ or t
649658
andBool START <=Int size(ELEMENTS) -Int END
650659
[preserves-definedness] // Indexes checked to be in range for ELEMENTS
651660
661+
rule <k> #traverseProjection(
662+
DEST,
663+
VAL,
664+
PointerOffset(OFFSET, ORIGIN_LENGTH) PROJS,
665+
CTXTS
666+
)
667+
=> #traverseProjection(
668+
DEST,
669+
Range(ListItem(VAL)),
670+
PointerOffset(OFFSET, ORIGIN_LENGTH) PROJS,
671+
CTXTS
672+
)
673+
...
674+
</k>
675+
requires notBool isRange(VAL)
676+
[preserves-definedness, priority(100)]
677+
652678
rule <k> #traverseProjection(
653679
DEST,
654680
Range(ELEMENTS),

kmir/src/kmir/kompile.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,15 @@ def _functions(kmir: KMIR, smir_info: SMIRInfo) -> dict[int, KInner]:
545545
'IntrinsicFunction',
546546
[KApply('symbol(_)_LIB_Symbol_String', [stringToken(sym['IntrinsicSym'])])],
547547
)
548+
elif 'NoOpSym' in sym:
549+
functions[ty] = KApply(
550+
'MonoItemKind::MonoItemFn',
551+
(
552+
KApply('symbol(_)_LIB_Symbol_String', (stringToken(sym['NoOpSym']),)),
553+
KApply('defId(_)_BODY_DefId_Int', (intToken(ty),)),
554+
KApply('noBody_BODY_MaybeBody', ()),
555+
),
556+
)
548557
elif isinstance(sym.get('NormalSym'), str):
549558
functions[ty] = KApply(
550559
'MonoItemKind::MonoItemFn',

kmir/src/tests/integration/data/exec-smir/intrinsic/blackbox_functions.expected.json

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33998,5 +33998,68 @@
3399833998
},
3399933999
"node": "KApply",
3400034000
"variable": false
34001+
},
34002+
"48": {
34003+
"args": [
34004+
{
34005+
"args": [
34006+
{
34007+
"node": "KToken",
34008+
"sort": {
34009+
"name": "String",
34010+
"node": "KSort"
34011+
},
34012+
"token": "\"\""
34013+
}
34014+
],
34015+
"arity": 1,
34016+
"label": {
34017+
"name": "symbol(_)_LIB_Symbol_String",
34018+
"node": "KLabel",
34019+
"params": []
34020+
},
34021+
"node": "KApply",
34022+
"variable": false
34023+
},
34024+
{
34025+
"args": [
34026+
{
34027+
"node": "KToken",
34028+
"sort": {
34029+
"name": "Int",
34030+
"node": "KSort"
34031+
},
34032+
"token": "48"
34033+
}
34034+
],
34035+
"arity": 1,
34036+
"label": {
34037+
"name": "defId(_)_BODY_DefId_Int",
34038+
"node": "KLabel",
34039+
"params": []
34040+
},
34041+
"node": "KApply",
34042+
"variable": false
34043+
},
34044+
{
34045+
"args": [],
34046+
"arity": 0,
34047+
"label": {
34048+
"name": "noBody_BODY_MaybeBody",
34049+
"node": "KLabel",
34050+
"params": []
34051+
},
34052+
"node": "KApply",
34053+
"variable": false
34054+
}
34055+
],
34056+
"arity": 3,
34057+
"label": {
34058+
"name": "MonoItemKind::MonoItemFn",
34059+
"node": "KLabel",
34060+
"params": []
34061+
},
34062+
"node": "KApply",
34063+
"variable": false
3400134064
}
3400234065
}

kmir/src/tests/integration/data/prove-rs/show/iterator-simple.main.expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
│ #execTerminator ( terminator ( ... kind: terminatorKindCall ( ... func: operandC
44
│ span: 0
55
6-
│ (798 steps)
6+
│ (1113 steps)
77
├─ 3 (terminal)
88
│ #EndProgram ~> .K
99
│ function: main

kmir/src/tests/unit/test_kompile.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
from __future__ import annotations
22

3+
from unittest.mock import Mock
4+
5+
from pyk.kast.inner import KApply
6+
from pyk.kast.prelude.kint import intToken
7+
from pyk.kast.prelude.string import stringToken
38
from pyk.kore.syntax import And, App, Axiom, EVar, Rewrites, SortApp, Top
49

5-
from kmir.kompile import _add_exists_quantifiers, _collect_evars
10+
from kmir.kompile import _add_exists_quantifiers, _collect_evars, _functions
11+
from kmir.smir import SMIRInfo
612

713

814
def test_collect_evars() -> None:
@@ -37,3 +43,31 @@ def test_add_exists_quantifiers() -> None:
3743
assert result.text.count(r'\exists') == 2
3844
assert 'VarA' in result.text
3945
assert 'VarB' in result.text
46+
47+
48+
def test_functions_preserve_noop_symbols() -> None:
49+
smir_info = SMIRInfo(
50+
{
51+
'name': 'noop-sym',
52+
'allocs': [],
53+
'functions': [[42, {'NoOpSym': ''}]],
54+
'uneval_consts': [],
55+
'items': [],
56+
'types': [],
57+
'spans': [],
58+
'debug': None,
59+
'machine': {},
60+
}
61+
)
62+
63+
kmir = Mock()
64+
kmir.parser = Mock()
65+
66+
assert _functions(kmir, smir_info)[42] == KApply(
67+
'MonoItemKind::MonoItemFn',
68+
(
69+
KApply('symbol(_)_LIB_Symbol_String', (stringToken(''),)),
70+
KApply('defId(_)_BODY_DefId_Int', (intToken(42),)),
71+
KApply('noBody_BODY_MaybeBody', ()),
72+
),
73+
)

0 commit comments

Comments
 (0)