fix invalid code gen for if v1==0 or v2==0

This commit is contained in:
Irmen de Jong 2024-07-01 23:05:53 +02:00
parent ddf990296b
commit e7298f8162
2 changed files with 5 additions and 4 deletions

View File

@ -59,16 +59,15 @@ internal class NotExpressionAndIfComparisonExprChanger(val program: Program, val
// integer case (only if both are the same type) // integer case (only if both are the same type)
val leftC = expr.left as? BinaryExpression val leftC = expr.left as? BinaryExpression
val rightC = expr.right as? BinaryExpression val rightC = expr.right as? BinaryExpression
if(leftC!=null && rightC!=null && leftC.operator=="==" && rightC.operator=="==") { if(expr.operator=="and" && leftC!=null && rightC!=null && leftC.operator=="==" && rightC.operator=="==") {
if (leftC.right.constValue(program)?.number == 0.0 && rightC.right.constValue(program)?.number == 0.0) { if (leftC.right.constValue(program)?.number == 0.0 && rightC.right.constValue(program)?.number == 0.0) {
val leftDt = leftC.left.inferType(program).getOr(DataType.UNDEFINED) val leftDt = leftC.left.inferType(program).getOr(DataType.UNDEFINED)
val rightDt = rightC.left.inferType(program).getOr(DataType.UNDEFINED) val rightDt = rightC.left.inferType(program).getOr(DataType.UNDEFINED)
if(leftDt==rightDt && leftDt in IntegerDatatypes) { if(leftDt==rightDt && leftDt in IntegerDatatypes) {
if (rightC.left.isSimple) { if (rightC.left.isSimple) {
// x==0 or y==0 -> (x & y)==0
// x==0 and y==0 -> (x | y)==0 // x==0 and y==0 -> (x | y)==0
val newOperator = if(expr.operator=="or") "&" else "|" // the 'or' case cannot be easily optimized with a binary and like this!
val inner = BinaryExpression(leftC.left, newOperator, rightC.left, expr.position) val inner = BinaryExpression(leftC.left, "|", rightC.left, expr.position)
val compare = BinaryExpression(inner, "==", NumericLiteral(leftDt, 0.0, expr.position), expr.position) val compare = BinaryExpression(inner, "==", NumericLiteral(leftDt, 0.0, expr.position), expr.position)
return listOf(IAstModification.ReplaceNode(expr, compare, parent)) return listOf(IAstModification.ReplaceNode(expr, compare, parent))
} }

View File

@ -8,6 +8,7 @@ other issues on github.
optimize signed byte/word division by powers of 2 (and shift right?), it's now using divmod routine. (also % ?) optimize signed byte/word division by powers of 2 (and shift right?), it's now using divmod routine. (also % ?)
see inplacemodificationByteVariableWithLiteralval() and inplacemodificationSomeWordWithLiteralval() see inplacemodificationByteVariableWithLiteralval() and inplacemodificationSomeWordWithLiteralval()
and for IR: see divideByConst() in IRCodeGen and for IR: see divideByConst() in IRCodeGen
1 shift right of AX signed word: 1 shift right of AX signed word:
stx P8ZP_SCRATCH_B1 stx P8ZP_SCRATCH_B1
cpx #$80 cpx #$80
@ -85,6 +86,7 @@ Libraries:
Optimizations: Optimizations:
- For 65c02 targets: use trb and tsb instructions if possible (f.ex. generating 'lda cmask' ' trb nvub' for 'nvub &= ~cmask' and 'lda cmask' 'and fillm' 'tsb nvub' for 'nvub |= cmask & fillm')
- VariableAllocator: can we think of a smarter strategy for allocating variables into zeropage, rather than first-come-first-served? - VariableAllocator: can we think of a smarter strategy for allocating variables into zeropage, rather than first-come-first-served?
for instance, vars used inside loops first, then loopvars, then uwords used as pointers, then the rest for instance, vars used inside loops first, then loopvars, then uwords used as pointers, then the rest
- various optimizers skip stuff if compTarget.name==VMTarget.NAME. Once 6502-codegen is done from IR code, - various optimizers skip stuff if compTarget.name==VMTarget.NAME. Once 6502-codegen is done from IR code,