Inlined call properly optimized, but not function itself

I saw something strange in the optimized LLVM code. It appears that
sometimes an inlined function is optimized though the function itself is
not optimized to the same level.

Below is an example of an unoptimized/non-inlined function call:

define void @_entry() uwtable {
entry:
  %0 = call i64 @eval_expr()
  call void @trace_integer(i64 %0)
  ret void
}

'eval_expr' is a big ugly series of branches, so I'm very happy that
LLVM figures it out and manages to optimize away the call entirely:

define void @_entry() uwtable {
entry:
  tail call void @trace_integer(i64 3)
  ret void
}

Obviously 'eval_expr' can be optimized to a constant value '3'. However,
the 'eval_expr' function doesn't actually reflect this optimization: it
still has a branch. Granted, it's a lot smaller than the input, but I'd
expect it to end up as just 'ret i64 3'.

define i64 @eval_expr() uwtable {
entry:
  %0 = extractvalue %0 { i1 true, i64 3 }, 0
  br i1 %0, label %switch_then_24, label %switch_end_2

switch_end_2: ; preds = %entry,
%switch_then_24
  %1 = phi i64 [ %2, %switch_then_24 ], [ 4, %entry ]
  ret i64 %1

switch_then_24: ; preds = %entry
  %2 = extractvalue %0 { i1 true, i64 3 }, 1
  br label %switch_end_2
}

In other situations the full reduction is done. It appears as I add
more branches the likelihood of it not happening increases. Why is this
happening and how can I fix it?

Hi edA-qa mort-ora-y,

define i64 @eval_expr() uwtable {
entry:
   %0 = extractvalue %0 { i1 true, i64 3 }, 0

it does seem odd that this has not been turned into "i1 true". The instcombine
pass, which is run many times in the standard optimization pipeline, will get
this. Are you running it?

Ciao, Duncan.