Question regarding preventing optimizing out of register in expansion

Nathan Sidwell
Thu Jun 21 13:12:00 GMT 2018

On 06/21/2018 05:20 AM, Peryt, Sebastian wrote:
> Hi,
> I'd appreciate if someone could advise me in builtin expansion I'm currently writing.
> High level description for what I want to do:
> I have 2 operands in my builtin.

IIUC you're defining an UNSPEC.

> First I set register (reg1) with value from operand1 (op1);
> Second I call my instruction (reg1 is called implicitly and updated);

Here is your error -- NEVER have implicit register settings.  The data 
flow analysers need accurate information.

> Simplified implementation in i386.c I have:
> reg1 = gen_reg_rtx (mode);
> emit_insn (gen_rtx_SET (reg1, op1); 
> emit_clobber (reg1);

At this point reg1 is dead.  That means the previous set of reg1 from 
op1 is unneeded and can be deleted.

> emit_insn (gen_myinstruction ());

This instruction has no inputs or outputs, and is not marked volatile(?) 
so can be deleted.

> emit_insn (gen_rtx_SET (op2,reg1));

And this is storing a value from a dead register.

You need something like:
   rtx reg1 = force_reg (op1);
   rtx reg2 = gen_reg_rtx (mode);
   emit_insn (gen_my_insn (reg2, reg1));
   emit insn (gen_rtx_SET (op2, reg2));

your instruction should be an UNSPEC showing what the inputs and outputs 
are.  That tells the optimizers what depends on what, but the compiler 
has no clue about what the transform is.

Nathan Sidwell

More information about the Gcc mailing list