diff --git a/compiler/nadd.pas b/compiler/nadd.pas index 751fb38449..b5282d3275 100644 --- a/compiler/nadd.pas +++ b/compiler/nadd.pas @@ -493,7 +493,7 @@ implementation t , vl, hp: tnode; lt,rt : tnodetype; hdef, - rd,ld : tdef; + rd,ld , inttype: tdef; rv,lv,v : tconstexprint; rvd,lvd : bestreal; ws1,ws2 : pcompilerwidestring; @@ -505,6 +505,7 @@ implementation res, b : boolean; cr, cl : Tconstexprint; + v2p, c2p, c1p, v1p: pnode; begin result:=nil; l1:=0; @@ -1255,6 +1256,74 @@ implementation exit; end; + { + (v1=const1) and (v2=const2) + can be converted into + ((v1 xor const1) or (v2 xor const2))=0 + } + if (nodetype=andn) and + (left.nodetype=equaln) and + (right.nodetype=equaln) and + (not might_have_sideeffects(left)) and + (not might_have_sideeffects(right)) and + (is_constintnode(taddnode(left).left) or is_constintnode(taddnode(left).right) or + is_constpointernode(taddnode(left).left) or is_constpointernode(taddnode(left).right)) and + (is_constintnode(taddnode(right).left) or is_constintnode(taddnode(right).right) or + is_constpointernode(taddnode(right).left) or is_constpointernode(taddnode(right).right)) then + begin + if is_constnode(taddnode(left).left) then + begin + v1p:=@taddnode(left).right; + c1p:=@taddnode(left).left; + end + else + begin + v1p:=@taddnode(left).left; + c1p:=@taddnode(left).right; + end; + if is_constnode(taddnode(right).left) then + begin + v2p:=@taddnode(right).right; + c2p:=@taddnode(right).left; + end + else + begin + v2p:=@taddnode(right).left; + c2p:=@taddnode(right).right; + end; + if v1p^.resultdef.size=v2p^.resultdef.size then + begin + if not(is_integer(v1p^.resultdef)) or not(is_integer(v2p^.resultdef)) then + begin + case v1p^.resultdef.size of + 2: + inttype:=u16inttype; + 4: + inttype:=u32inttype; + 8: + inttype:=u64inttype; + else + Internalerror(2020060101); + end; + + result:=caddnode.create_internal(equaln, + caddnode.create_internal(orn, + caddnode.create_internal(xorn,ctypeconvnode.create_internal(v1p^.getcopy,inttype), + ctypeconvnode.create_internal(c1p^.getcopy,inttype)), + caddnode.create_internal(xorn,ctypeconvnode.create_internal(v2p^.getcopy,inttype), + ctypeconvnode.create_internal(c2p^.getcopy,inttype)) + ), + cordconstnode.create(0,inttype,false)); + end + else + result:=caddnode.create_internal(equaln, + caddnode.create_internal(orn, + caddnode.create_internal(xorn,v1p^.getcopy,c1p^.getcopy), + caddnode.create_internal(xorn,v2p^.getcopy,c2p^.getcopy) + ), + cordconstnode.create(0,v1p^.resultdef,false)); + end; + end; { even when short circuit boolean evaluation is active, this optimization cannot be performed in case the node has side effects, because this can change the result (e.g., in an diff --git a/compiler/node.pas b/compiler/node.pas index 2b81f63377..709ec0bc07 100644 --- a/compiler/node.pas +++ b/compiler/node.pas @@ -741,7 +741,7 @@ implementation function is_constpointernode(p : tnode) : boolean; begin - is_constpointernode:=(p.nodetype=pointerconstn); + is_constpointernode:=(p.nodetype in [pointerconstn,niln]); end; function is_conststringnode(p : tnode) : boolean;