Release build with `debug = true` generates larger code (other than debug symbols)

It seems that release builds with debug = true somehow generates larger code.
I'm guessing that some optimizations are disabled in LLVM side?

Here is an example code generated for thumbv8m.main-none-eabi target.
Two instructions are added with debug = true as commented.

uxtb    r2, r0
addw    r0, pc, #12          # this instruction is added with debug = true
movs    r1, #0
add.w   r3, r0, r2, lsl #2   # this instruction is added too
tbb     [pc, r2]
cfstrseq        mvf0, [r7, #-40]        ; 0xffffffd8
andeq   r0, pc, r7, lsl #8
movs    r1, #1
movs    r0, #5
b.n     200047c2 
movs    r1, #1
movs    r0, #4
b.n     200047c2
movs    r1, #1
movs    r0, #0
b.n     200047c2
movs    r1, #1
movs    r0, #6
orr.w   r0, r1, r0, lsl #16
bx      lr

What I don't understand is that it seems r3 is never used.
Could it be a compiler bug?

Is there DWARF information in the executable? If so, you can check there what r3 is referring to.

debug = true also implies debug_assertions = true and overflow_checks = true.

edit: apparently they're connected to opt-level instead!

1 Like

Could you link some documentation stating where debug = true turns on debug_assertions and overflow_checks? The profiles section of The Cargo Book does not mention this.

debug_assertions and overflow-checks are enabled by default when opt-level is 0, and disabled by default when it is non-zero. The debug = true setting in the Cargo profile has no effect on these settings.

That wouldn't surprise me. AFAIK including debug information can sometimes disable things that would make the debugging experience particularly weird -- single-stepping heavily-optimized code can often have surprisingly little relationship to the input code.

1 Like

I've been looking at code gen.

For release build without debug = true:

# *** IR Dump After Live DEBUG_VALUE analysis ***
bb.0 (%ir-block.1):
  successors: %bb.1(0x12492492), %bb.4(0x24924925), %bb.3(0x24924924), %bb.2(0x12492492), %bb.5(0x12492492); %bb.1(14.29%), %bb.4(28.57%), %bb.3(28.57%), %bb.2(14.29%), %bb.5(14.29%)
  liveins: $r0
  renamable $r2 = tUXTB killed renamable $r0, 14, $noreg
  renamable $r0 = t2LEApcrelJT %jump-table.0, 14, $noreg
  renamable $r1, dead $cpsr = tMOVi8 0, 14, $noreg
  renamable $r3 = t2ADDrs killed renamable $r0, renamable $r2, 18, 14, $noreg, $noreg
  renamable $r0 = IMPLICIT_DEF
  t2BR_JT killed renamable $r3, killed renamable $r2, %jump-table.0

# *** IR Dump After ARM constant island placement and branch shortening pass ***:
bb.0 (%ir-block.1):
  successors: %bb.4(0x12492492), %bb.2(0x24924925), %bb.3(0x24924924), %bb.5(0x12492492), %bb.6(0x12492492); %bb.4(14.29%), %bb.2(28.57%), %bb.3(28.57%), %bb.5(14.29%), %bb.6(14.29%)
  liveins: $r0
  renamable $r2 = tUXTB killed renamable $r0, 14, $noreg
  renamable $r1, dead $cpsr = tMOVi8 0, 14, $noreg
  renamable $r0 = IMPLICIT_DEF
  t2TBB_JT $pc, killed $r2, %jump-table.0, 0

With debug = true

# *** IR Dump After Live DEBUG_VALUE analysis ***:
bb.0 (%ir-block.1):
  successors: %bb.1(0x12492492), %bb.4(0x24924925), %bb.3(0x24924924), %bb.2(0x12492492), %bb.5(0x12492492); %bb.1(14.29%), %bb.4(28.57%), %bb.3(28.57%), %bb.2(14.29%), %bb.5(14.29%)
  liveins: $r0
  DBG_VALUE $r0, $noreg, !"res", !DIExpression(), debug-location !25235; /home/shin/proj/sp/camellia/kernel/src/returncode.rs:0 line no:63
  DBG_VALUE $r0, $noreg, !"res", !DIExpression(), debug-location !25235; /home/shin/proj/sp/camellia/kernel/src/returncode.rs:0 line no:63
  renamable $r2 = tUXTB killed renamable $r0, 14, $noreg, debug-location !25236; /home/shin/proj/sp/camellia/kernel/src/returncode.rs:65:13
  renamable $r0 = t2LEApcrelJT %jump-table.0, 14, $noreg
  DBG_VALUE $r0, $noreg, !"res", !DIExpression(DW_OP_LLVM_entry_value, 1), debug-location !25235; /home/shin/proj/sp/camellia/kernel/src/returncode.rs:0 line no:63
  renamable $r1, dead $cpsr = tMOVi8 0, 14, $noreg
  renamable $r3 = t2ADDrs killed renamable $r0, renamable $r2, 18, 14, $noreg, $noreg
  renamable $r0 = IMPLICIT_DEF
  t2BR_JT killed renamable $r3, killed renamable $r2, %jump-table.0

# *** IR Dump After ARM constant island placement and branch shortening pass ***:
bb.0 (%ir-block.1):
  successors: %bb.4(0x12492492), %bb.2(0x24924925), %bb.3(0x24924924), %bb.5(0x12492492), %bb.6(0x12492492); %bb.4(14.29%), %bb.2(28.57%), %bb.3(28.57%), %bb.5(14.29%), %bb.6(14.29%)
  liveins: $r0
  DBG_VALUE $r0, $noreg, !"res", !DIExpression(), debug-location !25235; /home/shin/proj/sp/camellia/kernel/src/returncode.rs:0 line no:63
  DBG_VALUE $r0, $noreg, !"res", !DIExpression(), debug-location !25235; /home/shin/proj/sp/camellia/kernel/src/returncode.rs:0 line no:63
  renamable $r2 = tUXTB killed renamable $r0, 14, $noreg, debug-location !25236; /home/shin/proj/sp/camellia/kernel/src/returncode.rs:65:13
  renamable $r0 = t2LEApcrelJT %jump-table.0, 14, $noreg
  DBG_VALUE $r0, $noreg, !"res", !DIExpression(DW_OP_LLVM_entry_value, 1), debug-location !25235; /home/shin/proj/sp/camellia/kernel/src/returncode.rs:0 line no:63
  renamable $r1, dead $cpsr = tMOVi8 0, 14, $noreg
  renamable $r3 = t2ADDrs killed renamable $r0, renamable $r2, 18, 14, $noreg, $noreg
  renamable $r0 = IMPLICIT_DEF
  t2TBB_JT $pc, killed $r2, %jump-table.0, 0

It seems that after jump table is changed to use PC, r3 is no longer used and should have been removed, but it stays in the build with debug = true.

In LLVM code ARMConstantIslandPass.cpp there is a function called RemoveDeadAddBetweenLEAAndJT which seems responsible for removing the instruction. I had no time to further investigate the problem.

I'll go ahead and ask the LLVM guys since it looks like it is LLVM's problem.

1 Like

I just found that most of the changes were from -fno-omit-frame-pointer added to C compilation by the cc crate. (Had some C code bases in my project)
Still the above issue is valid.
However, I couldn't reproduce the problem.. I created the minimal example producing the exact same code but the problem is not reproduced.. I'll try debuging it inside LLVM if I have time..

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.