From a3f55cdf1fc6ea6cd49f199e235260ee38232460 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Wed, 9 Oct 2019 13:51:07 +0200 Subject: [PATCH] Regalloc solver: check that a variable doesn't exist to test if it can be added (fixes #1123); This situation could be triggered that can_add_var would return true while a variable was already added for the given register. For instance, when we have a reassignment (because of a fixed register input requirement) and a fixed input conflict on the same fixed register, this register will not be available in the regs_in set after inputs_done (because of the fixed input conflict diversion) but will have its own variable. --- cranelift/codegen/src/regalloc/solver.rs | 3 +- .../regalloc/solver-fixedconflict-var-2.clif | 100 ++++++++++ .../regalloc/solver-fixedconflict-var-3.clif | 137 ++++++++++++++ .../regalloc/solver-fixedconflict-var.clif | 173 ++++++++++++++++++ 4 files changed, 412 insertions(+), 1 deletion(-) create mode 100644 cranelift/filetests/filetests/regalloc/solver-fixedconflict-var-2.clif create mode 100644 cranelift/filetests/filetests/regalloc/solver-fixedconflict-var-3.clif create mode 100644 cranelift/filetests/filetests/regalloc/solver-fixedconflict-var.clif diff --git a/cranelift/codegen/src/regalloc/solver.rs b/cranelift/codegen/src/regalloc/solver.rs index 5a3e1df908..96ce702fdc 100644 --- a/cranelift/codegen/src/regalloc/solver.rs +++ b/cranelift/codegen/src/regalloc/solver.rs @@ -626,7 +626,7 @@ impl Solver { /// constraints if the value has already been added as a variable or fixed assignment. fn add_live_var(&mut self, value: Value, rc: RegClass, from: RegUnit, live_through: bool) { // Check for existing entries for this value. - if self.regs_in.is_avail(rc, from) { + if !self.can_add_var(rc, from) { // There could be an existing variable entry. if let Some(v) = self.vars.iter_mut().find(|v| v.value == value) { // We have an existing variable entry for `value`. Combine the constraints. @@ -969,6 +969,7 @@ impl Solver { /// Check if `value` can be added as a variable to help find a solution. pub fn can_add_var(&mut self, constraint: RegClass, from: RegUnit) -> bool { !self.regs_in.is_avail(constraint, from) + && !self.vars.iter().any(|var| var.from == Some(from)) } } diff --git a/cranelift/filetests/filetests/regalloc/solver-fixedconflict-var-2.clif b/cranelift/filetests/filetests/regalloc/solver-fixedconflict-var-2.clif new file mode 100644 index 0000000000..be64db792d --- /dev/null +++ b/cranelift/filetests/filetests/regalloc/solver-fixedconflict-var-2.clif @@ -0,0 +1,100 @@ +test compile +set opt_level=speed +set enable_pinned_reg=true +target x86_64 haswell + +function u0:0(i32, i32, i32, i64 vmctx) -> i64 uext system_v { +ebb0(v0: i32, v1: i32, v2: i32, v3: i64): + v236 = iconst.i32 0x4de9_bd37 + v424 = iconst.i32 0 + jump ebb37(v424) + +ebb37(v65: i32): + v433 = iconst.i32 0 + jump ebb40(v433) + +ebb40(v70: i32): + v75 = iconst.i32 0 + v259 = iconst.i32 0 + v78 -> v259 + v449 = iconst.i32 0 + v450, v451 = x86_sdivmodx v75, v449, v259 + v79 -> v450 + v269 = iconst.i32 0 + v270 = ushr_imm v269, 31 + v271 = iadd v269, v270 + v98 -> v271 + v100 = iconst.i32 -31 + v272 = iconst.i32 0x4de9_bd37 + v490, v273 = x86_smulx v100, v272 + v493 = iconst.i32 0 + jump ebb61(v493) + +ebb61(v103: i32): + v104 = iconst.i32 -23 + v105 = iconst.i32 -23 + v106 = popcnt v105 + v500 = sshr_imm v104, 31 + v501 = iconst.i32 0 + jump ebb64(v501) + +ebb64(v107: i32): + v108 = iconst.i32 0 + v109 = iconst.i32 0 + v278 = iconst.i32 0 + v507, v279 = x86_smulx v109, v278 + v280 = isub v279, v109 + v281 = sshr_imm v280, 11 + v282 = iconst.i32 0 + v283 = iadd v281, v282 + v111 -> v283 + v112 = rotr v108, v283 + jump ebb65 + +ebb65: + v509 = iconst.i32 0 + v510, v511 = x86_sdivmodx v107, v509, v112 + v113 -> v510 + v114 = iconst.i32 0 + v517 = iconst.i32 0 + v518, v519 = x86_sdivmodx v103, v517, v114 + v115 -> v518 + v534 = iconst.i32 0 + v122 -> v534 + v541 = iconst.i32 0 + v542, v543 = x86_sdivmodx v271, v541, v122 + v123 -> v542 + v289 = iconst.i32 0 + v125 -> v289 + v550 = iconst.i32 0 + v551, v552 = x86_sdivmodx v79, v550, v289 + v126 -> v551 + v130 = iconst.i32 0 + v558 = iconst.i32 0 + v559, v560 = x86_sdivmodx v70, v558, v130 + v131 -> v559 + v305 = iconst.i32 0 + v140 -> v305 + v577 = iconst.i32 0 + v578, v579 = x86_sdivmodx v65, v577, v305 + v141 -> v578 + v166 = iconst.i32 0 + v167 = iconst.i32 -31 + v318 = iconst.i32 0x4de9_bd37 + v650, v319 = x86_smulx v167, v318 + v320 = isub v319, v167 + v321 = sshr_imm v320, 4 + v322 = iconst.i32 0 + v323 = iadd v321, v322 + v169 -> v323 + v652 = iconst.i32 0 + v653, v654 = x86_sdivmodx v166, v652, v323 + v170 -> v653 + v171 = iconst.i32 -23 + v172 = iconst.i32 -23 + v173 = popcnt v172 + v174 = popcnt v173 + v660 = sshr_imm v171, 31 + v661, v662 = x86_sdivmodx v171, v660, v174 + trap user0 +} diff --git a/cranelift/filetests/filetests/regalloc/solver-fixedconflict-var-3.clif b/cranelift/filetests/filetests/regalloc/solver-fixedconflict-var-3.clif new file mode 100644 index 0000000000..13a613d1bf --- /dev/null +++ b/cranelift/filetests/filetests/regalloc/solver-fixedconflict-var-3.clif @@ -0,0 +1,137 @@ +test compile +set opt_level=speed +set enable_pinned_reg=true +target x86_64 haswell + +function u0:0(i32, i32, i32, i64 vmctx) -> i64 uext system_v { +ebb0(v0: i32, v1: i32, v2: i32, v3: i64): + v5 = iconst.i32 -8 + v114 = iconst.i32 0 + v16 = iconst.i32 -8 + v17 = popcnt v16 + v192 = ifcmp_imm v17, -1 + brif eq v192, ebb12 + trap user0 + +ebb12: + v122 = iconst.i32 0 + v123 = ushr_imm v122, 31 + v124 = iadd v122, v123 + v20 -> v124 + v25 = iconst.i32 -19 + v204 = iconst.i32 0 + v31 -> v204 + v210 = ifcmp_imm v31, -1 + brif eq v210, ebb18 + trap user0 + +ebb18: + v215 = iconst.i32 0 + jump ebb19(v215) + +ebb19(v32: i32): + v35 = iconst.i32 0 + v218 = ifcmp_imm v35, -1 + brif eq v218, ebb21 + trap user0 + +ebb21: + v223 = iconst.i32 0 + jump ebb22(v223) + +ebb22(v36: i32): + v136 = iconst.i32 0 + v40 -> v136 + v227 = ifcmp_imm v136, -1 + brif eq v227, ebb24 + trap user0 + +ebb24: + v232 = iconst.i32 0 + jump ebb25(v232) + +ebb25(v41: i32): + v142 = iconst.i32 0 + v45 -> v142 + v236 = ifcmp_imm v142, -1 + brif eq v236, ebb27 + trap user0 + +ebb27: + v241 = iconst.i32 0 + jump ebb28(v241) + +ebb28(v46: i32): + v49 = iconst.i32 0 + v244 = ifcmp_imm v49, -1 + brif eq v244, ebb30 + trap user0 + +ebb30: + v254 = iconst.i32 0 + v53 -> v254 + v54 = iconst.i32 -23 + v55 = popcnt v54 + v143 = iconst.i32 0x4de9_bd37 + v260, v144 = x86_smulx v55, v143 + v145 = iconst.i32 0 + v146 = sshr_imm v145, 4 + v147 = iconst.i32 0 + v148 = iadd v146, v147 + v57 -> v148 + v58 = ishl v53, v148 + jump ebb35 + +ebb35: + v262 = iconst.i32 0 + v263, v264 = x86_sdivmodx v46, v262, v58 + v59 -> v263 + v270 = iconst.i32 0 + v271, v272 = x86_sdivmodx v41, v270, v59 + v60 -> v271 + v61 = f32const 0.0 + v280 = iconst.i32 0 + v281 = fcmp uno v61, v61 + brnz v281, ebb41(v280) + trap user0 + +ebb41(v62: i32): + v157 = iconst.i32 0 + v158 = sshr_imm v157, 4 + v159 = iconst.i32 0 + v160 = iadd v158, v159 + v75 -> v160 + v308 = ifcmp_imm v160, -1 + brif eq v308, ebb52 + trap user0 + +ebb52: + v87 = iconst.i32 -23 + v88 = iconst.i32 -23 + v89 = popcnt v88 + v161 = iconst.i32 0x4de9_bd37 + v324, v162 = x86_smulx v89, v161 + v163 = isub v162, v89 + v164 = sshr_imm v163, 4 + v165 = iconst.i32 0 + v166 = iadd v164, v165 + v91 -> v166 + v326 = iconst.i32 0 + v327, v328 = x86_sdivmodx v87, v326, v166 + v92 -> v327 + v351 = iconst.i32 0 + v99 -> v351 + v358 = iconst.i32 0 + v359, v360 = x86_sdivmodx v36, v358, v99 + v100 -> v359 + v102 = iconst.i32 0 + v103 = rotr.i32 v32, v102 + v366 = iconst.i32 0 + v367, v368 = x86_sdivmodx v25, v366, v103 + v104 -> v367 + v383 = iconst.i32 0 + v107 -> v383 + v390 = iconst.i32 0 + v391, v392 = x86_sdivmodx v124, v390, v107 + trap user0 +} diff --git a/cranelift/filetests/filetests/regalloc/solver-fixedconflict-var.clif b/cranelift/filetests/filetests/regalloc/solver-fixedconflict-var.clif new file mode 100644 index 0000000000..fc643ddbd4 --- /dev/null +++ b/cranelift/filetests/filetests/regalloc/solver-fixedconflict-var.clif @@ -0,0 +1,173 @@ +test compile +set opt_level=speed +set enable_pinned_reg=true +target x86_64 haswell + +;; Test for the issue #1123; https://github.com/CraneStation/cranelift/issues/1123 + +function u0:0(i32, i32, i32, i64 vmctx) -> i64 uext system_v { +ebb0(v0: i32, v1: i32, v2: i32, v3: i64): + v351 = iconst.i32 0x4de9_bd37 + v31 = iconst.i32 -23 + v35 = iconst.i32 0 + v36 = iconst.i32 -31 + v357 = iconst.i32 0x4de9_bd37 + v530, v358 = x86_smulx v36, v357 + v359 = isub v358, v36 + v360 = sshr_imm v359, 4 + v361 = iconst.i32 0 + v362 = iadd v360, v361 + v38 -> v362 + v532 = sshr_imm v35, 31 + v533, v534 = x86_sdivmodx v35, v532, v362 + v39 -> v533 + v53 = iconst.i32 0 + v547 = ifcmp_imm v53, -1 + brif eq v547, ebb30 + trap user0 + +ebb30: + v75 = iconst.i32 0 + v581 = ifcmp_imm v75, -1 + brif eq v581, ebb42 + trap user0 + +ebb42: + v136 = iconst.i32 0 + v691 = ifcmp_imm v136, -1 + brif eq v691, ebb81 + trap user0 + +ebb81: + v158 = iconst.i32 0 + v725 = ifcmp_imm v158, -1 + brif eq v725, ebb93 + trap user0 + +ebb93: + v760 = iconst.i32 0 + jump ebb106(v760) + +ebb106(v175: i32): + v179 = iconst.i32 0 + v180 = icmp_imm eq v179, 0 + v183 = iconst.i32 0 + v766 = ifcmp_imm v183, -1 + brif eq v766, ebb108 + trap user0 + +ebb108: + v771 = iconst.i32 0 + jump ebb109(v771) + +ebb109(v184: i32): + v785 = iconst.i32 0 + v193 -> v785 + v791 = ifcmp_imm v193, -1 + brif eq v791, ebb117 + trap user0 + +ebb117: + v796 = iconst.i32 0 + jump ebb118(v796) + +ebb118(v194: i32): + v203 = iconst.i32 -63 + v809 = iconst.i32 0 + v207 -> v809 + v815 = ifcmp_imm v207, -1 + brif eq v815, ebb126 + trap user0 + +ebb126: + v209 = iconst.i32 0 + v823 = ifcmp_imm v209, -1 + brif eq v823, ebb129 + trap user0 + +ebb129: + v213 = iconst.i32 -23 + v214 = iconst.i32 -19 + v215 = icmp_imm eq v214, 0 + v216 = bint.i32 v215 + v217 = popcnt v216 + v435 = iconst.i32 0x7df7_df7d + v831, v436 = x86_smulx v217, v435 + v437 = isub v436, v217 + v438 = sshr_imm v437, 5 + v439 = ushr_imm v438, 31 + v440 = iadd v438, v439 + v219 -> v440 + v220 = rotr v213, v440 + v229 = iconst.i32 0 + v841 = iconst.i32 0 + v842, v843 = x86_sdivmodx v194, v841, v229 + v230 -> v842 + v849 = iconst.i32 0 + v850, v851 = x86_sdivmodx v184, v849, v230 + v231 -> v850 + v232 = iconst.i32 0 + v857 = iconst.i32 0 + v858, v859 = x86_sdivmodx v175, v857, v232 + v233 -> v858 + v915 = iconst.i32 0 + jump ebb163(v915) + +ebb163(v253: i32): + v255 = iconst.i32 0 + v256 = iconst.i32 -23 + v257 = iconst.i32 -19 + v258 = icmp_imm eq v257, 0 + v259 = bint.i32 v258 + v260 = popcnt v259 + v447 = iconst.i32 0x7df7_df7d + v921, v448 = x86_smulx v260, v447 + v449 = isub v448, v260 + v450 = sshr_imm v449, 5 + v451 = ushr_imm v450, 31 + v452 = iadd v450, v451 + v262 -> v452 + v263 = rotr v256, v452 + v264 = popcnt v263 + v265 = popcnt v264 + v266 = popcnt v265 + v267 = rotr v255, v266 + v268 = popcnt v267 + v923 = iconst.i32 0 + v924, v925 = x86_sdivmodx v253, v923, v268 + v269 -> v924 + v276 = iconst.i32 0 + v277 = iconst.i32 -63 + v278 = popcnt v277 + v947 = iconst.i32 0 + v948, v949 = x86_sdivmodx v276, v947, v278 + v279 -> v948 + v309 = iconst.i32 0 + v310 = iconst.i32 0 + v311 = iconst.i32 0 + v312 = icmp_imm eq v311, 0 + v313 = bint.i32 v312 + v314 = rotr v310, v313 + v315 = iconst.i32 -31 + v464 = iconst.i32 0 + v1020, v465 = x86_smulx v315, v464 + v466 = isub v465, v315 + v467 = sshr_imm v466, 4 + v468 = iconst.i32 0 + v469 = iadd v467, v468 + v317 -> v469 + v1022 = iconst.i32 0 + v1023, v1024 = x86_sdivmodx v314, v1022, v469 + v318 -> v1023 + v320 = iconst.i32 0 + v321 = iconst.i32 -19 + v322 = popcnt v321 + v1030 = iconst.i32 0 + v1031, v1032 = x86_sdivmodx v320, v1030, v322 + v323 -> v1031 + v1047 = iconst.i32 0 + v325 -> v1047 + v1054 = sshr_imm v309, 31 + v1055, v1056 = x86_sdivmodx v309, v1054, v325 + trap user0 +}