[LLVMdev] code generation removes duplicated instructions

Eli Friedman eli.friedman at gmail.com
Thu Jul 7 12:12:05 PDT 2011


On Thu, Jul 7, 2011 at 11:15 AM, D S Khudia <daya.khudia at gmail.com> wrote:
> Ok. Let me describe the problem again in some detail.
>
> The following is the original bitcode from a real testcase:
>
> bb7:
>   %46 = load i32* %j, align 4
>   %47 = add nsw i32 %46, 1
>   store i32 %47, i32* %j, align 4
>   br label %bb8
> To protect the operand of the store I duplicate the input chain of operands
> and insert a comparison to check whether the operand of the stores are
> correct. As a result of this modification the code looks as follows. Here
> instructions with HV in there name are extra inserted instructions and
> relExit BB contains a printf message which is executed if the
> comparison fails. This is the final code which is supposed to execute on a
> simulator or real hardware.
> bb7:
>   %46 = load i32* %j, align 4
>   %47 = add nsw i32 %46, 1
>   %HV7_ = add nsw i32 %46, 1
>   %HVCmp13 = icmp ne i32 %47, %HV7_
>   br i1 %HVCmp13, label %relExit, label %bb7.split
> bb7.split:
>   store i32 %47, i32* %j, align 4
>   br label %bb8
> The following is the arm code generated for the above block (llc with -O0):
> .LBB0_26:                               @ %bb7
>                                         @   in Loop: Header=BB0_28 Depth=2
>   ldr r0, [sp, #440]
>   add r0, r0, #1
>   cmp r0, r0
>   str r0, [sp, #288]
>   bne .LBB0_88
>   b .LBB0_27
> .LBB0_27:                               @ %bb7.split
>                                         @   in Loop: Header=BB0_28 Depth=2
>   ldr r0, [sp, #288]
>   str r0, [sp, #440]
> The code generated for x86 for the same two blocks looks like as follows
> (again llc with -O0):
> .LBB0_26:                               # %bb7
>                                               #   in Loop: Header=BB0_28
> Depth=2
>   movl  564(%esp), %eax
>   movl  %eax, 400(%esp)          # 4-byte Spill
>   addl  $1, %eax
>   movl  400(%esp), %ecx         # 4-byte Reload
>   addl  $1, %ecx
>   cmpl  %ecx, %eax
>   movl  %eax, 396(%esp)         # 4-byte Spill
>   jne .LBB0_88
> # BB#27:                               # %bb7.split
>                                             #   in Loop: Header=BB0_28
> Depth=2
>   movl  396(%esp), %eax         # 4-byte Reload
>   movl  %eax, 564(%esp)
> The problem here is in case of ARM code generation the backend has
> effectively removed the comparison (its comparing same register) of
> different computations. I want to have that comparison in the final code.
> The final code would be running on a hardware or simulator so that whenever
> a transient error occurs I can detect that and trigger a recovery. My goal
> here is to achieve the duplicated computation (same as visible in x86 asm
> e.g. adding the one twice) for ARM. Is there a way I can achieve it?
> Does the problem make more sense now? Thank you for your help.

You can hide the fact that the base values are the same from CodeGen
by writing the IR equivalent to something like the following C:
char* newval = val
asm("" : +r(newval));
if (&newval[3] != &val[3]) // Looks like a non-trivial comparison

-Eli




More information about the llvm-dev mailing list