Useless code:
#include <stdio.h>
void nop(void)
{
asm("nop");
}
int main(void)
{
asm("push %r10");
asm("movq $8, %r10");
asm("pop %r10");
for (int i=0; i<10000; i++)
{
nop();
}
return 0xdead;
}
compiled with the junk to:
0000000000001129 <nop>:
1129: 55 push rbp
112a: 48 89 e5 mov rbp,rsp
112d: 90 nop
112e: 90 nop
112f: 5d pop rbp
1130: c3 ret
0000000000001131 <main>:
1131: 55 push rbp
1132: 48 89 e5 mov rbp,rsp
1135: 48 83 ec 10 sub rsp,0x10
1139: 41 52 push r10
113b: 49 c7 c2 08 00 00 00 mov r10,0x8
1142: 41 5a pop r10
1144: c7 45 fc 00 00 00 00 mov DWORD PTR [rbp-0x4],0x0
114b: eb 09 jmp 1156 <main+0x25>
114d: e8 d7 ff ff ff call 1129 <nop>
1152: 83 45 fc 01 add DWORD PTR [rbp-0x4],0x1
1156: 81 7d fc 0f 27 00 00 cmp DWORD PTR [rbp-0x4],0x270f
115d: 7e ee jle 114d <main+0x1c>
115f: b8 ad de 00 00 mov eax,0xdead
1164: c9 leave
1165: c3 ret
% retdec-decompiler --select-decode-only --select-functions=nop,main ~/tmp/retdec-test/test
shit loop is still here:
define i64 @nop() local_unnamed_addr {
dec_label_pc_1129:
%0 = alloca i64, align 8
%1 = load i64, i64* %0, align 8
ret i64 %1, !insn.addr !0
}
define i64 @main(i64 %argc, i8** %argv) local_unnamed_addr {
dec_label_pc_1131:
%storemerge1.reg2mem = alloca i32, align 4, !insn.addr !1
store i32 0, i32* %storemerge1.reg2mem, align 4
br label %dec_label_pc_114d
dec_label_pc_114d: ; preds = %dec_label_pc_114d, %dec_label_pc_1131
%storemerge1.reload = load i32, i32* %storemerge1.reg2mem, align 4
%0 = call i64 @nop(), !insn.addr !2
%1 = add nuw nsw i32 %storemerge1.reload, 1, !insn.addr !3
%exitcond = icmp eq i32 %1, 10000
store i32 %1, i32* %storemerge1.reg2mem, align 4, !insn.addr !4
br i1 %exitcond, label %dec_label_pc_115f, label %dec_label_pc_114d, !insn.addr !4
dec_label_pc_115f: ; preds = %dec_label_pc_114d
ret i64 57005, !insn.addr !5
}
% clang -O2 -S -emit-llvm -o - test.ll > test_opt.ll
looks better now:
; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn
define i64 @nop() local_unnamed_addr #0 {
dec_label_pc_1129:
ret i64 undef, !insn.addr !0
}
; Function Attrs: nofree norecurse nosync nounwind readnone
define i64 @main(i64 %argc, i8** nocapture readnone %argv) local_unnamed_addr #1 {
dec_label_pc_1131:
ret i64 57005, !insn.addr !1
}
% llvm-as test_opt.ll -o test_opt.bc
% clang -nostdlib test_opt.bc -c -o test_opt.o
"optimized" code with a clean main:
% objdump -M intel -d test_opt.o
test_opt.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <nop>:
0: c3 ret
1: 66 2e 0f 1f 84 00 00 cs nop WORD PTR [rax+rax*1+0x0]
8: 00 00 00
b: 0f 1f 44 00 00 nop DWORD PTR [rax+rax*1+0x0]
0000000000000010 <main>:
10: b8 ad de 00 00 mov eax,0xdead
15: c3 ret