diff --git a/basis/compiler/cfg/builder/builder.factor b/basis/compiler/cfg/builder/builder.factor index 8dec435b9c..370f3d053f 100644 --- a/basis/compiler/cfg/builder/builder.factor +++ b/basis/compiler/cfg/builder/builder.factor @@ -137,7 +137,7 @@ M: #recursive emit-node : emit-actual-if ( #if -- ) ! Inputs to the final instruction need to be copied because of ! loc>vreg sync - ds-pop any-rep ^^copy \ f type-number cc/= ##compare-imm-branch emit-if ; + ds-pop any-rep ^^copy f cc/= ##compare-imm-branch emit-if ; M: #if emit-node { diff --git a/basis/compiler/cfg/value-numbering/rewrite/rewrite.factor b/basis/compiler/cfg/value-numbering/rewrite/rewrite.factor index 398c73c32c..81f39d7da2 100644 --- a/basis/compiler/cfg/value-numbering/rewrite/rewrite.factor +++ b/basis/compiler/cfg/value-numbering/rewrite/rewrite.factor @@ -134,17 +134,12 @@ M: ##compare-imm rewrite-tagged-comparison } cond swap cc= eq? [ [ negate-cc ] change-cc ] when ; -ERROR: bad-comparison ; - : (fold-compare-imm) ( insn -- ? ) - [ [ src1>> vreg>constant ] [ src2>> ] bi ] [ cc>> ] bi - pick integer? - [ [ <=> ] dip evaluate-cc ] - [ - 2nip { - { cc= [ f ] } - { cc/= [ t ] } - [ bad-comparison ] + [ src1>> vreg>constant ] [ src2>> ] [ cc>> ] tri + 2over [ integer? ] both? [ [ <=> ] dip evaluate-cc ] [ + { + { cc= [ eq? ] } + { cc/= [ eq? not ] } } case ] if ; @@ -253,7 +248,12 @@ M: ##shl-imm constant-fold* drop shift ; : constant-fold ( insn -- insn' ) [ dst>> ] - [ [ src1>> vreg>constant ] [ src2>> ] [ ] tri constant-fold* ] bi + [ + [ src1>> vreg>constant \ f type-number or ] + [ src2>> ] + [ ] + tri constant-fold* + ] bi \ ##load-immediate new-insn ; inline : unary-constant-fold? ( insn -- ? ) @@ -379,7 +379,7 @@ M: ##sar-imm rewrite [ drop f ] } cond ; -: insn>imm-insn ( insn op swap? -- ) +: insn>imm-insn ( insn op swap? -- new-insn ) swap [ [ [ dst>> ] [ src1>> ] [ src2>> ] tri ] dip [ swap ] when vreg>constant @@ -389,13 +389,13 @@ M: ##sar-imm rewrite arithmetic-op? [ vreg-immediate-arithmetic? ] [ vreg-immediate-bitwise? ] if ; -: rewrite-arithmetic ( insn op -- ? ) +: rewrite-arithmetic ( insn op -- insn/f ) { { [ over src2>> over vreg-immediate? ] [ f insn>imm-insn ] } [ 2drop f ] } cond ; inline -: rewrite-arithmetic-commutative ( insn op -- ? ) +: rewrite-arithmetic-commutative ( insn op -- insn/f ) { { [ over src2>> over vreg-immediate? ] [ f insn>imm-insn ] } { [ over src1>> over vreg-immediate? ] [ t insn>imm-insn ] } diff --git a/basis/compiler/cfg/value-numbering/value-numbering-tests.factor b/basis/compiler/cfg/value-numbering/value-numbering-tests.factor index 7e41df69d6..f835200702 100644 --- a/basis/compiler/cfg/value-numbering/value-numbering-tests.factor +++ b/basis/compiler/cfg/value-numbering/value-numbering-tests.factor @@ -519,6 +519,59 @@ cpu x86.32? [ } value-numbering-step trim-temps ] unit-test +! Branch folding +[ + { + T{ ##load-immediate f 1 100 } + T{ ##load-immediate f 2 200 } + T{ ##load-constant f 3 t } + } +] [ + { + T{ ##load-immediate f 1 100 } + T{ ##load-immediate f 2 200 } + T{ ##compare f 3 1 2 cc<= } + } value-numbering-step trim-temps +] unit-test + +[ + { + T{ ##load-immediate f 1 100 } + T{ ##load-immediate f 2 200 } + T{ ##load-constant f 3 f } + } +] [ + { + T{ ##load-immediate f 1 100 } + T{ ##load-immediate f 2 200 } + T{ ##compare f 3 1 2 cc= } + } value-numbering-step trim-temps +] unit-test + +[ + { + T{ ##load-immediate f 1 100 } + T{ ##load-constant f 2 f } + } +] [ + { + T{ ##load-immediate f 1 100 } + T{ ##compare-imm f 2 1 f cc= } + } value-numbering-step trim-temps +] unit-test + +[ + { + T{ ##load-constant f 1 f } + T{ ##load-constant f 2 t } + } +] [ + { + T{ ##load-constant f 1 f } + T{ ##compare-imm f 2 1 f cc= } + } value-numbering-step trim-temps +] unit-test + ! Reassociation [ { @@ -1042,6 +1095,19 @@ cell 8 = [ } value-numbering-step ] unit-test +! Stupid constant folding corner case +[ + { + T{ ##load-constant f 1 f } + T{ ##load-immediate f 2 $[ \ f type-number ] } + } +] [ + { + T{ ##load-constant f 1 f } + T{ ##and-imm f 2 1 15 } + } value-numbering-step +] unit-test + ! Displaced alien optimizations 3 vreg-counter set-global diff --git a/basis/cpu/x86/x86.factor b/basis/cpu/x86/x86.factor index 220db859d0..bab90c0f09 100644 --- a/basis/cpu/x86/x86.factor +++ b/basis/cpu/x86/x86.factor @@ -521,7 +521,7 @@ M:: x86 %compare ( dst src1 src2 cc temp -- ) { [ 3dup use-test? ] [ 2drop dup TEST ] } { [ over integer? ] [ drop CMP ] } { [ over word? ] [ drop (%compare-tagged) ] } - { [ over not ] [ 2drop f type-number CMP ] } + { [ over not ] [ 2drop \ f type-number CMP ] } } cond ; M:: x86 %compare-imm ( dst src1 src2 cc temp -- )