@@ -265,6 +265,48 @@ func TestClobbersArg1(t *testing.T) {
265265 }
266266}
267267
268+ func TestNoRematerializeDeadConstant (t * testing.T ) {
269+ c := testConfigARM64 (t )
270+ f := c .Fun ("b1" ,
271+ Bloc ("b1" ,
272+ Valu ("mem" , OpInitMem , types .TypeMem , 0 , nil ),
273+ Valu ("addr" , OpArg , c .config .Types .Int32 .PtrTo (), 0 , c .Temp (c .config .Types .Int32 .PtrTo ())),
274+ Valu ("const" , OpARM64MOVDconst , c .config .Types .Int32 , - 1 , nil ), // Original constant
275+ Valu ("cmp" , OpARM64CMPconst , types .TypeFlags , 0 , nil , "const" ),
276+ Goto ("b2" ),
277+ ),
278+ Bloc ("b2" ,
279+ Valu ("phi_mem" , OpPhi , types .TypeMem , 0 , nil , "mem" , "callmem" ),
280+ Eq ("cmp" , "b6" , "b3" ),
281+ ),
282+ Bloc ("b3" ,
283+ Valu ("call" , OpARM64CALLstatic , types .TypeMem , 0 , AuxCallLSym ("_" ), "phi_mem" ),
284+ Valu ("callmem" , OpSelectN , types .TypeMem , 0 , nil , "call" ),
285+ Eq ("cmp" , "b5" , "b4" ),
286+ ),
287+ Bloc ("b4" , // A block where we don't really need to rematerialize the constant -1
288+ Goto ("b2" ),
289+ ),
290+ Bloc ("b5" ,
291+ Valu ("user" , OpAMD64MOVQstore , types .TypeMem , 0 , nil , "addr" , "const" , "callmem" ),
292+ Exit ("user" ),
293+ ),
294+ Bloc ("b6" ,
295+ Exit ("phi_mem" ),
296+ ),
297+ )
298+
299+ regalloc (f .f )
300+ checkFunc (f .f )
301+
302+ // Check that in block b4, there's no dead rematerialization of the constant -1
303+ for _ , v := range f .blocks ["b4" ].Values {
304+ if v .Op == OpARM64MOVDconst && v .AuxInt == - 1 {
305+ t .Errorf ("constant -1 rematerialized in loop block b4: %s" , v .LongString ())
306+ }
307+ }
308+ }
309+
268310func numSpills (b * Block ) int {
269311 return numOps (b , OpStoreReg )
270312}
0 commit comments