[llvm-dev] TwoAddressInstructionPass bug?

Quentin Colombet via llvm-dev llvm-dev at lists.llvm.org
Thu Nov 30 10:39:02 PST 2017


Hi Jonas,

Thanks for bringing that up.

> On Nov 30, 2017, at 4:04 AM, Jonas Paulsson via llvm-dev <llvm-dev at lists.llvm.org> wrote:
> 
> Hi,
> 
> we are in the midst of an interesting work that begun with setting 'guessInstructionProperties = 0' in the SystemZ backend. We have found this to be useful, and discovered many instructions where the hasSideEffects flag was incorrectly set while it actually shouldn't.
> 
> The attached patch and test case triggers an assert in TwoAddress.  (bin/llc ./tc_TwoAddr_crash.ll -mtriple=s390x-linux-gnu -mcpu=z13)
> 
> The only change in the patch is to remove the side effects flag from one instruction:
> 
> -  def RISBMux : RotateSelectRIEfPseudo<GRX32, GRX32>;
> +  let hasSideEffects = 0 in
> +    def RISBMux : RotateSelectRIEfPseudo<GRX32, GRX32>;
> 
> The input to TwoAddress is:
> 
> BB#0: derived from LLVM BB %0
>     Live Ins: %r2l
>         %vreg0<def> = COPY %r2l<kill>; GR32Bit:%vreg0
>         %vreg9<def,tied1> = NIFMux %vreg0<tied0>, 14, %cc<imp-def,dead>; GRX32Bit:%vreg9 GR32Bit:%vreg0
>         %vreg4<def,tied1> = NIFMux %vreg0<tied0>, 254, %cc<imp-def,dead>; GRX32Bit:%vreg4 GR32Bit:%vreg0
>         %vreg2<def> = COPY %vreg0<kill>; GR32Bit:%vreg2,%vreg0
>         %vreg3<def> = COPY %vreg9<kill>; GR32Bit:%vreg3 GRX32Bit:%vreg9
> 
>         ...
> 
> The NIFMux instructions will be converted by the SystemZ backend into RISBMux instructions. The tied source operand of the RISBMux is 0 (no-register / undef). This seems necessary as this is after 'Process implicit defs' pass.
> 
> The big change with the patch is that TwoAddress is now able to reschedule the RISBMux close to the killing instruction:
> 
> 1: MBB->dump() = BB#0: derived from LLVM BB %0
>     Live Ins: %r2l
>         %vreg0<def> = COPY %r2l<kill>; GR32Bit:%vreg0
>         %vreg4<def,tied1> = NIFMux %vreg0<tied0>, 254, %cc<imp-def,dead>; GRX32Bit:%vreg4 GR32Bit:%vreg0
>         %vreg2<def> = COPY %vreg0; GR32Bit:%vreg2,%vreg0
>         %vreg9<def,tied1> = RISBMux %noreg<tied0>, %vreg0<kill>, 28, 158, 0; GRX32Bit:%vreg9 GR32Bit:%vreg0
>         %vreg3<def> = COPY %vreg9<kill>; GR32Bit:%vreg3 GRX32Bit:%vreg9
> 
>         ...
> 
> This however means that TwoAddress will encounter this instruction once more as it iterates through MBB. That's when the assert triggers:
> 
> assert(SrcReg && SrcMO.isUse() && "two address instruction invalid");
> 
> It seems to me that since the %noreg makes sense (per above), and TwoAddress wants to schedule this instruction down the block, this assert is wrong here.

I agree.

> 
> Should TwoAddress have a set of rescheduled instructions and not revisit them while iterating over MBB? Or is target allowed to actually build new 2-addr instructions here (seems odd)?

Having a set of rescheduled instructions and skipping them sounds reasonable to me.

Cheers,
-Quentin
> 
> One alternative might be to first make a set of original instructions and only process them.
> 
> /Jonas
> 
> 
> 
> <RISBMux_noSEFlag.patch><tc_TwoAddr_crash.ll>_______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev



More information about the llvm-dev mailing list