Home | History | Annotate | Download | only in JumpThreading
      1 ; RUN: opt -S -jump-threading < %s | FileCheck %s
      2 
      3 declare void @foo()
      4 declare void @bar()
      5 declare void @baz()
      6 declare void @quux()
      7 
      8 
      9 ; Jump threading of branch with select as condition.
     10 ; Mostly theoretical since instruction combining simplifies all selects of
     11 ; booleans where at least one operand is true/false/undef.
     12 
     13 ; CHECK: @test_br
     14 ; CHECK-NEXT: entry:
     15 ; CHECK-NEXT: br i1 %cond, label %L1,
     16 define void @test_br(i1 %cond, i1 %value) nounwind {
     17 entry:
     18   br i1 %cond, label %L0, label %L3
     19 L0:
     20   %expr = select i1 %cond, i1 true, i1 %value
     21   br i1 %expr, label %L1, label %L2
     22 
     23 L1:
     24   call void @foo()
     25   ret void
     26 L2:
     27   call void @bar()
     28   ret void
     29 L3:
     30   call void @baz()
     31   br label %L0
     32 }
     33 
     34 
     35 ; Jump threading of switch with select as condition.
     36 
     37 ; CHECK: @test_switch
     38 ; CHECK-NEXT: entry:
     39 ; CHECK-NEXT: br i1 %cond, label %L1,
     40 define void @test_switch(i1 %cond, i8 %value) nounwind {
     41 entry:
     42   br i1 %cond, label %L0, label %L4
     43 L0:
     44   %expr = select i1 %cond, i8 1, i8 %value
     45   switch i8 %expr, label %L3 [i8 1, label %L1 i8 2, label %L2]
     46 
     47 L1:
     48   call void @foo()
     49   ret void
     50 L2:
     51   call void @bar()
     52   ret void
     53 L3:
     54   call void @baz()
     55   ret void
     56 L4:
     57   call void @quux()
     58   br label %L0
     59 }
     60 
     61 ; Make sure the blocks in the indirectbr test aren't trivially removable as
     62 ; successors by taking their addresses.
     63 @anchor = constant [3 x i8*] [
     64   i8* blockaddress(@test_indirectbr, %L1),
     65   i8* blockaddress(@test_indirectbr, %L2),
     66   i8* blockaddress(@test_indirectbr, %L3)
     67 ]
     68 
     69 
     70 ; Jump threading of indirectbr with select as address.
     71 
     72 ; CHECK: @test_indirectbr
     73 ; CHECK-NEXT: entry:
     74 ; CHECK-NEXT: br i1 %cond, label %L1, label %L3
     75 define void @test_indirectbr(i1 %cond, i8* %address) nounwind {
     76 entry:
     77   br i1 %cond, label %L0, label %L3
     78 L0:
     79   %indirect.goto.dest = select i1 %cond, i8* blockaddress(@test_indirectbr, %L1), i8* %address
     80   indirectbr i8* %indirect.goto.dest, [label %L1, label %L2, label %L3]
     81 
     82 L1:
     83   call void @foo()
     84   ret void
     85 L2:
     86   call void @bar()
     87   ret void
     88 L3:
     89   call void @baz()
     90   ret void
     91 }
     92 
     93 
     94 ; A more complicated case: the condition is a select based on a comparison.
     95 
     96 ; CHECK: @test_switch_cmp
     97 ; CHECK-NEXT: entry:
     98 ; CHECK-NEXT: br i1 %cond, label %L0, label %[[THREADED:[A-Za-z.0-9]+]]
     99 ; CHECK: [[THREADED]]:
    100 ; CHECK-NEXT: call void @quux
    101 ; CHECK-NEXT: br label %L1
    102 define void @test_switch_cmp(i1 %cond, i32 %val, i8 %value) nounwind {
    103 entry:
    104   br i1 %cond, label %L0, label %L4
    105 L0:
    106   %val.phi = phi i32 [%val, %entry], [-1, %L4]
    107   %cmp = icmp slt i32 %val.phi, 0
    108   %expr = select i1 %cmp, i8 1, i8 %value
    109   switch i8 %expr, label %L3 [i8 1, label %L1 i8 2, label %L2]
    110 
    111 L1:
    112   call void @foo()
    113   ret void
    114 L2:
    115   call void @bar()
    116   ret void
    117 L3:
    118   call void @baz()
    119   ret void
    120 L4:
    121   call void @quux()
    122   br label %L0
    123 }
    124