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.
This commit is contained in:
Benjamin Bouvier
2019-10-09 13:51:07 +02:00
committed by Dan Gohman
parent beca77c2f8
commit a3f55cdf1f
4 changed files with 412 additions and 1 deletions

View File

@@ -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))
}
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}