Skip to content

Instantly share code, notes, and snippets.

@mraleph
Created October 9, 2014 19:59
Show Gist options
  • Save mraleph/2a2a1c6b6106c7c1d46c to your computer and use it in GitHub Desktop.
Save mraleph/2a2a1c6b6106c7c1d46c to your computer and use it in GitHub Desktop.
#include <stdint.h>
/* clang version 3.5.0 (trunk 214024) */
void f(uint32_t* p) {
while (__builtin_uadd_overflow(*p, 1, p)) {
p++;
}
}
/* Loop from `f` compiled with `-target armv7a-none-eabi -O3`
Notice that: adds is not used and bool is materialized.
.LBB0_1: @ %while.cond
@ =>This Inner Loop Header: Depth=1
ldr r1, [r0]
add r2, r1, #1
str r2, [r0], #4
cmp r2, r1
mov r1, #1
movwhs r1, #0
cmp r1, #0
bne .LBB0_1
*/
/* Loop from `f` compiled with `-target aarch64-none-eabi -O3`
WAT? `adds` is used but we still materialize and dematerialize bool into `w9`.
.LBB0_1: // %while.cond
// =>This Inner Loop Header: Depth=1
ldr w8, [x0]
adds w8, w8, #1 // =1
cset w9, hs
str w8, [x0], #4
tbnz w9, #0, .LBB0_1
*/
/* NOW LETS GET FUNKY */
void g(uint32_t* p) {
if (*p) {
while (__builtin_uadd_overflow(*p, 1, p)) {
p++;
}
} else {
*p = 1;
}
}
/* Loop from `g` compiled with `-target armv7a-none-eabi -O3`
Notice that: adds is not used and bool is materialized.
Value of the *p is forwarded on the loop entry edge, hence the strange
post/pre increments choice.
add r0, r0, #4
.LBB1_2: @ %while.cond
@ =>This Inner Loop Header: Depth=1
add r3, r1, #1
sub r2, r0, #4
cmp r3, r1
mov r1, #1
movwhs r1, #0
cmp r1, #0
str r3, [r2]
bxeq lr
ldr r1, [r0], #4
b .LBB1_2
*/
/*
Loop from `g` compiled with `-target aarch64-none-eabi -O3`
HOORAY b.hs is used.
// BB#1: // %while.cond.preheader
add x8, x0, #4 // =4
b .LBB1_3
.LBB1_2: // %while.cond.while.cond_crit_edge
// in Loop: Header=BB1_3 Depth=1
ldr w9, [x8], #4
.LBB1_3: // %while.cond
// =>This Inner Loop Header: Depth=1
adds w9, w9, #1 // =1
stur w9, [x8, #-4]
b.hs .LBB1_2
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment