Condition removed? Difference between LLVM and GCC on a small testcase

Hello Dev,

I have a very simple testcase, which shows strange difference between LLVM and GCC. Does anyone know which optimization pass removes the condition? Thanks!

C code:

extern void bar(int, int);

void foo(int a) {

int b, d;

if (a > 114) {

b = a * 58;

} else {

d = a * 51;

}

bar(b, d);

}

clang.7.0.1 -O2, LLVM generated assembly:

0: 6b c7 3a imul $0x3a,%edi,%eax

3: 6b f7 33 imul $0x33,%edi,%esi

6: 89 c7 mov %eax,%edi

8: e9 00 00 00 00 jmpq d <foo+0xd>

GCC.5.2.0 -O3, GCC generated assembly:

0: 83 ff 72 cmp $0x72,%edi

3: 7f 0b jg 10 <foo+0x10>

5: 6b f7 33 imul $0x33,%edi,%esi

8: 89 c7 mov %eax,%edi

f: 90 nop

10: 6b c7 3a imul $0x3a,%edi,%eax

13: 89 c7 mov %eax,%edi

15: e9 00 00 00 00 jmpq 1a <foo+0x1a>

Regards,

Yan

SimplifyCFG converts branching conditions into equivalents with the
LLVM "select" instruction (think cmov on x86), and then CSE (common
subexpression elimination) removes the select entirely on the grounds
that the other branch is undefined (it could in principle be anything,
so a*51 or a*58 is as good a value as any to assume).

Cheers.

Tim.

Tim,

Thanks for the reply! It makes sense that LLVM selects a*51 or a*58 for an undefined value although it makes the arguments to bar() "predictable".

Regards,
Yan

It seems like undefined behavior to me right? So we could even eliminate the call to bar() entirely (making it even more “predictable” ;))