I am currently working on famous System Programming problem, "Bomb lab" phase2. When I disassembled phase_2 with gdb, code looks like this...
Phase_2
0x00005555555555cb <+0>: endbr64
0x00005555555555cf <+4>: push %rbp
0x00005555555555d0 <+5>: push %rbx
0x00005555555555d1 <+6>: sub $0x28,%rsp
0x00005555555555d5 <+10>: mov %fs:0x28,%rax
0x00005555555555de <+19>: mov %rax,0x18(%rsp)
0x00005555555555e3 <+24>: xor %eax,%eax
0x00005555555555e5 <+26>: mov %rsp,%rsi
0x00005555555555e8 <+29>: callq 0x555555555bd5 <read_six_numbers>
0x00005555555555ed <+34>: cmpl $0x0,(%rsp)
0x00005555555555f1 <+38>: js 0x5555555555fd <phase_2+50>
0x00005555555555f3 <+40>: mov %rsp,%rbp
0x00005555555555f6 <+43>: mov $0x1,%ebx
0x00005555555555fb <+48>: jmp 0x555555555615 <phase_2+74>
0x00005555555555fd <+50>: callq 0x555555555ba9 <explode_bomb>
0x0000555555555602 <+55>: jmp 0x5555555555f3 <phase_2+40>
0x0000555555555604 <+57>: callq 0x555555555ba9 <explode_bomb>
0x0000555555555609 <+62>: add $0x1,%ebx
0x000055555555560c <+65>: add $0x4,%rbp
0x0000555555555610 <+69>: cmp $0x6,%ebx
0x0000555555555613 <+72>: je 0x555555555621 <phase_2+86>
0x0000555555555615 <+74>: mov %ebx,%eax
0x0000555555555617 <+76>: add 0x0(%rbp),%eax
0x000055555555561a <+79>: cmp %eax,0x4(%rbp)
0x000055555555561d <+82>: je 0x555555555609 <phase_2+62>
0x000055555555561f <+84>: jmp 0x555555555604 <phase_2+57>
0x0000555555555621 <+86>: mov 0x18(%rsp),%rax
0x0000555555555626 <+91>: xor %fs:0x28,%rax
0x000055555555562f <+100>: jne 0x555555555638 <phase_2+109>
0x0000555555555631 <+102>: add $0x28,%rsp
0x0000555555555635 <+106>: pop %rbx
0x0000555555555636 <+107>: pop %rbp
0x0000555555555637 <+108>: retq
0x0000555555555638 <+109>: callq 0x555555555220 <__stack_chk_fail#plt>
I guess that in line <+62>, %ebx means index, and increments the value until the value is 6 (by line <+69>). But I don't really understand lines such as
0x000055555555560c <+65>: add $0x4,%rbp
or
0x0000555555555615 <+74>: mov %ebx,%eax
0x0000555555555617 <+76>: add 0x0(%rbp),%eax
0x000055555555561a <+79>: cmp %eax,0x4(%rbp)
I guess it is probably related to features of sequence that I have to find, but I don't understand why values such as 0x4(%rbp)is compared with %eax etc... Can someone explain?
Related
I'm trying to create an encryption/decryption program using c++ and assembly. I was originally using 3 different arrays, the original string, the encrypted string, and the decrypted string. I'm now trying to convert this to a 2D array and I'm having trouble adding an encrypted character to the second line of the array.
__asm
{
push eax
push ebx
push ecx
push edx
xor ebx, ebx
jmp checkend
forloop1: add ebx, 1
checkend: cmp ebx, aLength
jge endfor1
movzx ecx, byte ptr[Chars + ebx]
lea eax, EKey
push ecx
mov edi, eax
movzx eax, byte ptr[eax]
and eax, 0x3f
rol al, 1
mov byte ptr[edi], al
cmp eax, 0x00
jnz zerocheck
mov eax, 0x09
zerocheck:mov edx, eax
pop eax
sub eax, edx
rol al, 1
not al
mov byte ptr [Chars + ebx * 2], al // this line here
jmp forloop1
endfor1:
pop edx
pop ecx
pop ebx
pop eax
}
return;
I can read in the first row fine, which is where the string entered is stored. I've marked the line where I'm trying to get the encrypted character to be stored in the second line the array but everything I've tried doesn't seem to work. The [Chars + ebx * 2] is what isn't working. I know that the 2 on the end isn't the correct value, can anyone tell me what value I should be adding/multiplying on the end to get to the second line of the array. Any help would be appreciated.
Managed to get this working. All I had to do was add this line of code first;
mov edx, aLength
Where aLength is the length of the array, and then use that to get the second line in the array like so;
mov byte ptr [Chars + ebx + edx], al
I am getting a crash in MMC code. The dump is pointing to p->QueryInterface(GetIID(), reinterpret_cast<void**>(&pInterface));
The disassembly shows as below,
//fill method is called.
BSecRem!std::fill<int *,int>:
5d931510 8b442404 mov eax,[esp+0x4]
5d931514 8b4c2408 mov ecx,[esp+0x8]
5d931518 3bc1 cmp eax,ecx
5d93151a 7411 jz BSecRem!std::fill<int *,int>+0x1d (5d93152d)
5d93151c 8b54240c mov edx,[esp+0xc]
5d931520 56 push esi
5d931521 8b32 mov esi,[edx]
5d931523 8930 mov [eax],esi
5d931525 83c004 add eax,0x4
5d931528 3bc1 cmp eax,ecx
5d93152a 75f5 jnz BSecRem!std::fill<int *,int>+0x11 (5d931521)
5d93152c 5e pop esi
5d93152d c3 ret
5d93152e cc int 3
5d93152f cc int 3
BSecRem!stdext::_Unchecked_move_backward<int *,int *>:
5d931530 8b442408 mov eax,[esp+0x8]
5d931534 8b542404 mov edx,[esp+0x4]
5d931538 2bc2 sub eax,edx
5d93153a c1f802 sar eax,0x2
5d93153d 56 push esi
5d93153e 8b742410 mov esi,[esp+0x10]
5d931542 8d0c8500000000 lea ecx,[00000000+eax*4]
5d931549 2bf1 sub esi,ecx
5d93154b 85c0 test eax,eax
5d93154d 7e0d jle BSecRem!stdext::_Unchecked_move_backward<int *,int *>+0x2c (5d93155c)
5d93154f 51 push ecx
5d931550 52 push edx
5d931551 51 push ecx
5d931552 56 push esi
5d931553 ff15e034a65d call dword ptr [BSecRem!_imp__memmove_s (5da634e0)]
5d931559 83c410 add esp,0x10
5d93155c 8bc6 mov eax,esi
5d93155e 5e pop esi
5d93155f c3 ret
BSecRem!_com_ptr_t<_com_IIID<PATENTTEMPOCXLib::_DPatentTempOCX,&_GUID_6042985e_c7cc_4286_b5c4_48a347173739> >::_QueryInterface<IUnknown *>:
5d931560 8b442404 mov eax,[esp+0x4]
5d931564 56 push esi
5d931565 8bf1 mov esi,ecx
5d931567 85c0 test eax,eax
5d931569 7439 jz instant.dll!_com_ptr_t<_com_IIID<PATENTTEMPOCXLib::_DPatentTempOCX,&_GUID_7072787e_ddeb_1223_9aab4_9aab4d923e31> >::_QueryInterface<IUnknown *>+0x44 (5d9315a4)
5d93156b 8b08 mov ecx,[eax]
5d93156d 53 push ebx
5d93156e 57 push edi
5d93156f 8d542410 lea edx,[esp+0x10]
5d931573 52 push edx
5d931574 68cc54a65d push 0x5da654cc
5d931579 50 push eax
5d93157a 8b01 mov eax,[ecx] ds:002b:0000000c=???????
The crash is seen frequently. Specially when I navigate from one interface to other interface of MMC.
Thanks in advance.
Based on the technique described here I'm setting ivars in object instances using the ivar_getOffset() method.
Now I have the case where the ivar is a NSString*:
NSString* _name;
UPDATE:
I was on the wrong track (can't use ivar_getOffset in this case), I should be using:
object_setIvar(target, _ivar, [stringValue copy]);
to assign object values to ivars.
My question remains: is this safe to do under ARC? Will the ivar's existing object be properly released by ARC?
I'm worried that ARC might not properly release whatever string the ivar was set to before the assignment. Though I doubt it, otherwise the compiler wouldn't let me like in the case of object_setInstanceVariable ("not available in automatic reference counting mode") - right?
Yes, doing this with ARC is legal, at least in Mac OS X 10.8.2
If you would disassemble libobjc, you would find this:
================ B E G I N O F P R O C E D U R E ================
; Basic Block Input Regs: rdx rsi rdi - Killed Regs: rbx rbp r15
_object_setIvar:
000000000000c1f5 55 push rbp ; XREF=0xc1e1
000000000000c1f6 4889E5 mov rbp, rsp
000000000000c1f9 4157 push r15
000000000000c1fb 4156 push r14
000000000000c1fd 4155 push r13
000000000000c1ff 4154 push r12
000000000000c201 53 push rbx
000000000000c202 4883EC18 sub rsp, 0x18
000000000000c206 488955C8 mov qword [ss:rbp-0x40+var_8], rdx
000000000000c20a 4889F3 mov rbx, rsi
000000000000c20d 4989FF mov r15, rdi
000000000000c210 4D85FF test r15, r15
000000000000c213 0F8449010000 je 0xc362
; Basic Block Input Regs: rbx - Killed Regs: <nothing>
000000000000c219 4885DB test rbx, rbx
000000000000c21c 0F8440010000 je 0xc362
; Basic Block Input Regs: r15 - Killed Regs: rax
000000000000c222 41F6C701 test r15L, 0x1
000000000000c226 4C89F8 mov rax, r15
000000000000c229 740F je 0xc23a
; Basic Block Input Regs: <nothing> - Killed Regs: rax
000000000000c22b 4883E00F and rax, 0xf
000000000000c22f 48C1E003 shl rax, 0x3
000000000000c233 4803057ECE1000 add rax, qword [ds:0x1190b8]
; Basic Block Input Regs: rax rbx - Killed Regs: rdx rbp rsi rdi r12
000000000000c23a 4C8B20 mov r12, qword [ds:rax] ; XREF=0xc229
000000000000c23d 48C745D000000000 mov qword [ss:rbp-0x40+var_16], 0x0
000000000000c245 4889DF mov rdi, rbx
000000000000c248 E805F5FFFF call _ivar_getName
000000000000c24d 488D55D0 lea rdx, qword [ss:rbp-0x40+var_16]
000000000000c251 4C89E7 mov rdi, r12
000000000000c254 4889C6 mov rsi, rax
000000000000c257 E8C9E7FFFF call __class_getVariable
000000000000c25c 4885C0 test rax, rax
000000000000c25f 7433 je 0xc294
; Basic Block Input Regs: <nothing> - Killed Regs: r14
000000000000c261 4C8D75D0 lea r14, qword [ss:rbp-0x40+var_16]
000000000000c265 EB1F jmp 0xc286
; Basic Block Input Regs: rax rbx r12 r14 - Killed Regs: rdx rbp rsi rdi
000000000000c267 E88EC3FFFF call __class_getSuperclass ; XREF=0xc292
000000000000c26c 488945D0 mov qword [ss:rbp-0x40+var_16], rax
000000000000c270 4889DF mov rdi, rbx
000000000000c273 E8DAF4FFFF call _ivar_getName
000000000000c278 4C89E7 mov rdi, r12
000000000000c27b 4889C6 mov rsi, rax
000000000000c27e 4C89F2 mov rdx, r14
000000000000c281 E89FE7FFFF call __class_getVariable
; Basic Block Input Regs: rax rbx - Killed Regs: <nothing>
000000000000c286 4839D8 cmp rax, rbx ; XREF=0xc265
000000000000c289 7409 je 0xc294
; Basic Block Input Regs: rbp - Killed Regs: rdi
000000000000c28b 488B7DD0 mov rdi, qword [ss:rbp-0x40+var_16]
000000000000c28f 4885FF test rdi, rdi
000000000000c292 75D3 jne 0xc267
; Basic Block Input Regs: rax rbx rbp - Killed Regs: rbx rdi r12 r13
000000000000c294 4C8B6DD0 mov r13, qword [ss:rbp-0x40+var_16] ; XREF=0xc25f, 0xc289
000000000000c298 4889DF mov rdi, rbx
000000000000c29b E8B3F2FFFF call _ivar_getOffset
000000000000c2a0 4889C3 mov rbx, rax
000000000000c2a3 4D8D241F lea r12, qword [ds:r15+rbx]
000000000000c2a7 4C89EF mov rdi, r13
000000000000c2aa E8B3F2FFFF call __class_usesAutomaticRetainRelease
000000000000c2af 84C0 test al, al
000000000000c2b1 746B je 0xc31e
; Basic Block Input Regs: rax r13 - Killed Regs: rdi r14
000000000000c2b3 4C89EF mov rdi, r13
000000000000c2b6 E840A00000 call __class_getInstanceStart
000000000000c2bb 4189C6 mov r14d, eax
000000000000c2be 4C89EF mov rdi, r13
000000000000c2c1 E80EA80000 call _class_getWeakIvarLayout
000000000000c2c6 4885C0 test rax, rax
000000000000c2c9 7423 je 0xc2ee
; Basic Block Input Regs: rax rbx r14 - Killed Regs: rcx rsi rdi
000000000000c2cb 4489F1 mov ecx, r14d
000000000000c2ce 4889DF mov rdi, rbx
000000000000c2d1 4829CF sub rdi, rcx
000000000000c2d4 4889C6 mov rsi, rax
000000000000c2d7 E8483C0000 call __ZL17is_scanned_offsetlPKh ; is_scanned_offset(long, unsigned char const*)
000000000000c2dc 84C0 test al, al
000000000000c2de 740E je 0xc2ee
; Basic Block Input Regs: rbp r12 - Killed Regs: rsi rdi
000000000000c2e0 4C89E7 mov rdi, r12
000000000000c2e3 488B75C8 mov rsi, qword [ss:rbp-0x40+var_8]
000000000000c2e7 E82B440100 call _objc_storeWeak
000000000000c2ec EB74 jmp 0xc362
; Basic Block Input Regs: rax r13 - Killed Regs: rdi
000000000000c2ee 4C89EF mov rdi, r13 ; XREF=0xc2c9, 0xc2de
000000000000c2f1 E8C5A70000 call _class_getIvarLayout
000000000000c2f6 4885C0 test rax, rax
000000000000c2f9 7423 je 0xc31e
; Basic Block Input Regs: rax rbx r14 - Killed Regs: rcx rsi rdi
000000000000c2fb 4489F1 mov ecx, r14d
000000000000c2fe 4889DF mov rdi, rbx
000000000000c301 4829CF sub rdi, rcx
000000000000c304 4889C6 mov rsi, rax
000000000000c307 E8183C0000 call __ZL17is_scanned_offsetlPKh ; is_scanned_offset(long, unsigned char const*)
000000000000c30c 84C0 test al, al
000000000000c30e 740E je 0xc31e
; Basic Block Input Regs: rbp r12 - Killed Regs: rsi rdi
000000000000c310 4C89E7 mov rdi, r12
000000000000c313 488B75C8 mov rsi, qword [ss:rbp-0x40+var_8]
000000000000c317 E8044C0100 call _objc_storeStrong
000000000000c31c EB44 jmp 0xc362
; Basic Block Input Regs: <nothing> - Killed Regs: <nothing>
000000000000c31e 803DEB49110000 cmp byte [ds:_UseGC], 0x0 ; XREF=0xc2b1, 0xc2f9, 0xc30e
000000000000c325 7428 je 0xc34f
; Basic Block Input Regs: rax r13 - Killed Regs: rdi
000000000000c327 4C89EF mov rdi, r13
000000000000c32a E8A5A70000 call _class_getWeakIvarLayout
000000000000c32f 4885C0 test rax, rax
000000000000c332 741B je 0xc34f
; Basic Block Input Regs: rax rbx - Killed Regs: rsi rdi
000000000000c334 4889DF mov rdi, rbx
000000000000c337 4889C6 mov rsi, rax
000000000000c33a E8E53B0000 call __ZL17is_scanned_offsetlPKh ; is_scanned_offset(long, unsigned char const*)
000000000000c33f 84C0 test al, al
000000000000c341 740C je 0xc34f
; Basic Block Input Regs: rbp r12 - Killed Regs: rsi rdi
000000000000c343 488B7DC8 mov rdi, qword [ss:rbp-0x40+var_8]
000000000000c347 4C89E6 mov rsi, r12
000000000000c34a E831230000 call _objc_assign_weak
; Basic Block Input Regs: rbx rbp r15 - Killed Regs: rax rdx rsi rdi
000000000000c34f 488D055AE51000 lea rax, qword [ds:_objc_assign_ivar_internal] ; XREF=0xc325, 0xc332, 0xc341
000000000000c356 488B7DC8 mov rdi, qword [ss:rbp-0x40+var_8]
000000000000c35a 4C89FE mov rsi, r15
000000000000c35d 4889DA mov rdx, rbx
000000000000c360 FF10 call qword [ds:rax]
; Basic Block Input Regs: <nothing> - Killed Regs: rbx rsp rbp r12 r13 r14 r15
000000000000c362 4883C418 add rsp, 0x18 ; XREF=0xc213, 0xc21c, 0xc2ec, 0xc31c
000000000000c366 5B pop rbx
Note the call of _class_usesAutomaticRetainRelease at 000000000000c2aa.
The implementation of this method is available at opensource.apple.com
The header comment to this functions is:
/***********************************************************************
* _class_usesAutomaticRetainRelease
* Returns YES if class was compiled with -fobjc-arc
**********************************************************************/
Which means this particular function of ObjC runtime is aware of ARC.
I don't know the answer, but I know how to determine the answer...
Create an ivar that points to an instance of a class of your own, like LC2DFoo. Put a breakpoint in -[LC2DFoo dealloc]. Create an instance of LC2DFoo and assign it to the ivar using the runtime method you describe. Next, set the same ivar to something else, like nil. Do you hit your breakpoint?
I am trying to figure out which method objc_msgSend() will call.
While looking at assembly of any function in Appkit or Cocoa or Any framework based on Objective-C framework, I always get stucked at objc_msgSend().
Does any one has any idea how to reach the actual function call from here?
I remember while browsing I have seen some open source code which was kind of Map for which function will be called based on selector (integer value). I guess it was from Apple (not sure). I am trying to find that link from almost 2 days, but cannot find it. If anyone who that link please share.
In following assembly, I am trying to solve this call
__text:001C6E46 call _objc_msgSend
It should be great, if some one can help me understand the complete procedure.
__text:001C6DC0 ; -[NSWindow _windowMovedToRect:]
__text:001C6DC0 __NSWindow__windowMovedToRect__ proc near ; DATA XREF: __inst_meth:00993418o
__text:001C6DC0
__text:001C6DC0 var_C = dword ptr -0Ch
__text:001C6DC0 arg_0 = dword ptr 8
__text:001C6DC0 arg_8 = dword ptr 10h
__text:001C6DC0 arg_C = dword ptr 14h
__text:001C6DC0 arg_10 = dword ptr 18h
__text:001C6DC0 arg_14 = dword ptr 1Ch
__text:001C6DC0
__text:001C6DC0 push ebp
__text:001C6DC1 mov ebp, esp
__text:001C6DC3 push esi
__text:001C6DC4 push ebx
__text:001C6DC5 sub esp, 30h
__text:001C6DC8 call $+5
__text:001C6DCD pop ebx
__text:001C6DCE mov esi, [ebp+arg_0]
__text:001C6DD1 lea eax, [ebp+var_C]
__text:001C6DD4 mov [esp], eax
__text:001C6DD7 call _PSbuttondown
__text:001C6DDC mov edx, [ebp+var_C]
__text:001C6DDF test edx, edx
__text:001C6DE1 jz short loc_1C6E1D
__text:001C6DE3 mov eax, [esi+80h]
__text:001C6DE9 or dword ptr [eax+0B8h], 1000000h
__text:001C6DF3 mov eax, [ebp+arg_8]
__text:001C6DF6 mov edx, [ebp+arg_C]
__text:001C6DF9 mov [esp+8], eax
__text:001C6DFD mov [esp+0Ch], edx
__text:001C6E01 mov eax, [esi+8]
__text:001C6E04 mov edx, [esi+0Ch]
__text:001C6E07 mov [esp], eax
__text:001C6E0A mov [esp+4], edx
__text:001C6E0E call _NSEqualPoints
__text:001C6E13 test al, al
__text:001C6E15 jnz loc_1C6ED6
__text:001C6E1B jmp short loc_1C6E50
__text:001C6E1D ; ---------------------------------------------------------------------------
__text:001C6E1D
__text:001C6E1D loc_1C6E1D: ; CODE XREF: -[NSWindow _windowMovedToRect:]+21j
__text:001C6E1D mov eax, [ebp+arg_8]
__text:001C6E20 mov [esp+8], eax
__text:001C6E24 mov eax, [ebp+arg_C]
__text:001C6E27 mov [esp+0Ch], eax
__text:001C6E2B mov eax, [ebp+arg_10]
__text:001C6E2E mov [esp+10h], eax
__text:001C6E32 mov eax, [ebp+arg_14]
__text:001C6E35 mov [esp+14h], eax
__text:001C6E39 mov eax, ds:(off_926DC8 - 1C6DCDh)[ebx]
__text:001C6E3F mov [esp+4], eax
__text:001C6E43 mov [esp], esi
__text:001C6E46 call _objc_msgSend
__text:001C6E4B jmp loc_1C6ED6
__text:001C6E50 ; ---------------------------------------------------------------------------
__text:001C6E50
__text:001C6E50 loc_1C6E50: ; CODE XREF: -[NSWindow _windowMovedToRect:]+5Bj
__text:001C6E50 mov eax, [ebp+arg_8]
__text:001C6E53 mov [esp+8], eax
__text:001C6E57 mov eax, [ebp+arg_C]
__text:001C6E5A mov [esp+0Ch], eax
__text:001C6E5E mov eax, [ebp+arg_10]
__text:001C6E61 mov [esp+10h], eax
__text:001C6E65 mov eax, [ebp+arg_14]
__text:001C6E68 mov [esp+14h], eax
__text:001C6E6C mov eax, ds:(off_91D198 - 1C6DCDh)[ebx]
__text:001C6E72 mov [esp+4], eax
__text:001C6E76 mov [esp], esi
__text:001C6E79 call _objc_msgSend
__text:001C6E7E mov eax, ds:(off_91A4B8 - 1C6DCDh)[ebx]
__text:001C6E84 mov [esp+4], eax
__text:001C6E88 mov eax, ds:(off_928EE8 - 1C6DCDh)[ebx]
__text:001C6E8E mov [esp], eax
__text:001C6E91 call _objc_msgSend
__text:001C6E96 mov [esp+0Ch], esi
__text:001C6E9A mov edx, ds:(_NSWindowDidMoveNotification_ptr - 1C6DCDh)[ebx]
__text:001C6EA0 mov edx, [edx]
__text:001C6EA2 mov [esp+8], edx
__text:001C6EA6 mov edx, ds:(off_91B0DC - 1C6DCDh)[ebx]
__text:001C6EAC mov [esp+4], edx
__text:001C6EB0 mov [esp], eax
__text:001C6EB3 call _objc_msgSend
__text:001C6EB8 mov eax, ds:(_NSAccessibilityMovedNotification_ptr - 1C6DCDh)[ebx]
__text:001C6EBE mov eax, [eax]
__text:001C6EC0 mov [esp+8], eax
__text:001C6EC4 mov eax, ds:(off_91B030 - 1C6DCDh)[ebx]
__text:001C6ECA mov [esp+4], eax
__text:001C6ECE mov [esp], esi
__text:001C6ED1 call _objc_msgSend
__text:001C6ED6
__text:001C6ED6 loc_1C6ED6: ; CODE XREF: -[NSWindow _windowMovedToRect:]+55j
__text:001C6ED6 ; -[NSWindow _windowMovedToRect:]+8Bj
__text:001C6ED6 add esp, 30h
__text:001C6ED9 pop ebx
__text:001C6EDA pop esi
__text:001C6EDB leave
__text:001C6EDC retn
__text:001C6EDC __NSWindow__windowMovedToRect__ endp
This site mentions a tool called otx that appears to decode the selector for you.
Should I avoid using the 'insertvalue' instruction combined with load and store when I emit LLVM code?
I always get bad optimized native code when I use it. Look at the following example:
; ModuleID = 'mod'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-pc-linux-gnu"
%A = type { i64, i64, i64, i64, i64, i64, i64, i64 }
#aa = external global %A*
define void #func() {
entry:
%a1 = load %A** #aa
%a2 = load %A* %a1
%a3 = insertvalue %A %a2, i64 3, 3
store %A %a3, %A* %a1
ret void
}
When I run "llc -o - -O3 mod.ll", I get this horrible code:
func: # #func
.Ltmp0:
.cfi_startproc
# BB#0: # %entry
movq aa(%rip), %rax
movq (%rax), %r8
movq 8(%rax), %r9
movq 16(%rax), %r10
movq 32(%rax), %rdi
movq 40(%rax), %rcx
movq 48(%rax), %rdx
movq 56(%rax), %rsi
movq %rsi, 56(%rax)
movq %rdx, 48(%rax)
movq %rcx, 40(%rax)
movq %rdi, 32(%rax)
movq %r10, 16(%rax)
movq %r9, 8(%rax)
movq %r8, (%rax)
movq $3, 24(%rax)
ret
But what I would like to see is this:
func: # #func
.Ltmp0:
.cfi_startproc
# BB#0: # %entry
movq aa(%rip), %rax
movq $3, 24(%rax)
ret
Of course I can use getelementptr or something, but sometimes it is easier to generate insertvalue and extractvalue instructions, and I want these to be optimized...
I think it would be quite easy for the codegen to see that things like these are bad:
movq 56(%rax), %rsi
movq %rsi, 56(%rax)
First, note that llc does not do any IR-level optimizations. So, you should run opt to run the set of IR-level optimizers.
However, opt does not help in this. I'd expect that standard IR-level optimizers canonicalize the stuff into gep somehow.
Please file a LLVM PR, this looks like a missed optimization!