Souper says:
; Function: fn2
%0 = block
%1:i32 = var
%2:i32 = lshr %1, 31:i32
%3:i32 = var
%4:i32 = udiv %2, %3
%5:i1 = eq 0:i32, %3
%6:i32 = zext %5
%7:i32 = phi %0, %4, %6
%8:i32 = ashr %7, 1:i32
%9:i1 = eq 0:i32, %8
cand %9 1:i1
COMMAND: /home/regehr/souper/build/souper -stp-path=/usr/local/bin/stp reduce_543/foo.bc
LLVM says:
define i32 @fn1(i32 %p1) #0 {
entry:
%0 = load i32* @a, align 4, !tbaa !1
%cmp = icmp eq i32 %0, 0
%conv = zext i1 %cmp to i32
br i1 %cmp, label %cond.end, label %cond.false
cond.false: ; preds = %entry
%div = udiv i32 %p1, %0
br label %cond.end
cond.end: ; preds = %entry, %cond.false
%cond = phi i32 [ %div, %cond.false ], [ %conv, %entry ]
ret i32 %cond
}
define void @fn2() #1 {
entry:
%0 = load i32** @b, align 8, !tbaa !5
%.pre = load i32* @a, align 4, !tbaa !1
br label %for.cond
for.cond: ; preds = %fn1.exit, %entry
%cmp.i = icmp eq i32 %.pre, 0
%conv.i = zext i1 %cmp.i to i32
br i1 %cmp.i, label %fn1.exit, label %cond.false.i
cond.false.i: ; preds = %for.cond
%1 = load i32* %0, align 4, !tbaa !1
%.lobit = lshr i32 %1, 31
%div.i = udiv i32 %.lobit, %.pre
br label %fn1.exit
fn1.exit: ; preds = %for.cond, %cond.false.i
%cond.i = phi i32 [ %div.i, %cond.false.i ], [ %conv.i, %for.cond ]
store i32 %cond.i, i32* @d, align 4, !tbaa !1
%shr = ashr i32 %cond.i, 1
store i32 %shr, i32* @c, align 4, !tbaa !1
%tobool = icmp eq i32 %shr, 0
br i1 %tobool, label %for.cond, label %for.end
for.end: ; preds = %fn1.exit
ret void
}
COMMAND: /home/regehr/souper/third_party/llvm/Debug/bin/clang -c -w -emit-llvm -O3 reduce_543/foo.c -o reduce_543/foo.bc
C source code:
int a, c, d;
int *b;
int fn1(unsigned p1) { return a == 0 ?: p1 / a; }
void fn2() {
for (;;) {
d = fn1(0 > *b);
c = d >> 1;
if (c)
break;
}
}
x86-64 from LLVM:
fn1: # @fn1
movl a(%rip), %ecx
testl %ecx, %ecx
sete %al
je .LBB0_1
xorl %edx, %edx
movl %edi, %eax
divl %ecx
retq
.LBB0_1:
movzbl %al, %eax
retq
fn2: # @fn2
movq b(%rip), %rcx
movl a(%rip), %esi
.LBB1_1: # %for.cond
testl %esi, %esi
sete %al
jne .LBB1_3
movzbl %al, %eax
jmp .LBB1_4
.LBB1_3: # %cond.false.i
movl (%rcx), %eax
shrl $31, %eax
xorl %edx, %edx
divl %esi
.LBB1_4: # %fn1.exit
movl %eax, d(%rip)
sarl %eax
movl %eax, c(%rip)
je .LBB1_1
retq
.Ltmp1:
COMMAND: /home/regehr/souper/third_party/llvm/Debug/bin/clang -w -O3 reduce_543/foo.c -S -o -
x86-64 from GCC:
fn1:
movl a(%rip), %ecx
movl $1, %eax
testl %ecx, %ecx
je .L2
movl %edi, %eax
xorl %edx, %edx
divl %ecx
.L2:
rep ret
fn2:
.LFB1:
movl a(%rip), %ecx
movq b(%rip), %rsi
testl %ecx, %ecx
jne .L8
.L9:
jmp .L9
.L8:
movl (%rsi), %eax
xorl %edx, %edx
movl $0, c(%rip)
shrl $31, %eax
divl %ecx
movl %eax, d(%rip)
jmp .L8
.LFE1:
COMMAND: gcc -w -O3 reduce_543/foo.c -S -o -