Skip to content
README.txt 62.3 KiB
Newer Older
.LBB0_2:
	jmp	foo  # TAILCALL
//===---------------------------------------------------------------------===//
Given a branch where the two target blocks are identical ("ret i32 %b" in
both), simplifycfg will simplify them away. But not so for a switch statement:

define i32 @f(i32 %a, i32 %b) nounwind readnone {
entry:
        switch i32 %a, label %bb3 [
                i32 4, label %bb
                i32 6, label %bb
        ]
bb:             ; preds = %entry, %entry
        ret i32 %b

bb3:            ; preds = %entry
        ret i32 %b
}
//===---------------------------------------------------------------------===//

clang -O3 fails to devirtualize this virtual inheritance case: (GCC PR45875)
Chris Lattner's avatar
Chris Lattner committed
Looks related to PR3100

struct c1 {};
struct c10 : c1{
  virtual void foo ();
};
struct c11 : c10, c1{
  virtual void f6 ();
};
struct c28 : virtual c11{
  void f6 ();
};
void check_c28 () {
  c28 obj;
  c11 *ptr = &obj;
  ptr->f6 ();
}

//===---------------------------------------------------------------------===//
Chris Lattner's avatar
Chris Lattner committed

We compile this:

int foo(int a) { return (a & (~15)) / 16; }

Into:

define i32 @foo(i32 %a) nounwind readnone ssp {
entry:
  %and = and i32 %a, -16
  %div = sdiv i32 %and, 16
  ret i32 %div
}

but this code (X & -A)/A is X >> log2(A) when A is a power of 2, so this case
should be instcombined into just "a >> 4".

We do get this at the codegen level, so something knows about it, but 
instcombine should catch it earlier:

_foo:                                   ## @foo
## BB#0:                                ## %entry
	movl	%edi, %eax
	sarl	$4, %eax
	ret

//===---------------------------------------------------------------------===//

Chris Lattner's avatar
Chris Lattner committed
This code (from GCC PR28685):

int test(int a, int b) {
  int lt = a < b;
  int eq = a == b;
  if (lt)
    return 1;
  return eq;
}

Is compiled to:

define i32 @test(i32 %a, i32 %b) nounwind readnone ssp {
entry:
  %cmp = icmp slt i32 %a, %b
  br i1 %cmp, label %return, label %if.end

if.end:                                           ; preds = %entry
  %cmp5 = icmp eq i32 %a, %b
  %conv6 = zext i1 %cmp5 to i32
  ret i32 %conv6

return:                                           ; preds = %entry
  ret i32 1
}

it could be:

define i32 @test__(i32 %a, i32 %b) nounwind readnone ssp {
entry:
  %0 = icmp sle i32 %a, %b
  %retval = zext i1 %0 to i32
  ret i32 %retval
}

//===---------------------------------------------------------------------===//