Home | History | Annotate | Download | only in SimplifyCFG
      1 ; RUN: opt -S -simplifycfg < %s | FileCheck %s
      2 
      3 declare void @llvm.experimental.guard(i1, ...)
      4 
      5 define i32 @f_0(i1 %c) {
      6 ; CHECK-LABEL: @f_0(
      7 ; CHECK-NEXT: entry:
      8 ; CHECK-NEXT:  call void (i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ]
      9 ; CHECK-NEXT:  unreachable
     10 entry:
     11   call void(i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ]
     12   ret i32 10
     13 }
     14 
     15 define i32 @f_1(i1 %c) {
     16 ; Demonstrate that we (intentionally) do not simplify a guard on undef
     17 
     18 ; CHECK-LABEL: @f_1(
     19 ; CHECK: ret i32 10
     20 ; CHECK: ret i32 20
     21 
     22 entry:
     23   br i1 %c, label %true, label %false
     24 
     25 true:
     26   call void(i1, ...) @llvm.experimental.guard(i1 undef) [ "deopt"() ]
     27   ret i32 10
     28 
     29 false:
     30   ret i32 20
     31 }
     32 
     33 define i32 @f_2(i1 %c, i32* %buf) {
     34 ; CHECK-LABEL: @f_2(
     35 entry:
     36   br i1 %c, label %guard_block, label %merge_block
     37 
     38 guard_block:
     39   call void(i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ]
     40   %val = load i32, i32* %buf
     41   br label %merge_block
     42 
     43 merge_block:
     44   %to.return = phi i32 [ %val, %guard_block ], [ 50, %entry ]
     45   ret i32 %to.return
     46 ; CHECK: guard_block:
     47 ; CHECK-NEXT:  call void (i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ]
     48 ; CHECK-NEXT:  unreachable
     49 
     50 ; CHECK: merge_block:
     51 ; CHECK-NEXT:  ret i32 50
     52 }
     53 
     54 define i32 @f_3(i1* %c, i32* %buf) {
     55 ; CHECK-LABEL: @f_3(
     56 entry:
     57   %c0 = load volatile i1, i1* %c
     58   br i1 %c0, label %guard_block, label %merge_block
     59 
     60 guard_block:
     61   call void(i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ]
     62   %val = load i32, i32* %buf
     63   %c2 = load volatile i1, i1* %c
     64   br i1 %c2, label %left, label %right
     65 
     66 merge_block:
     67   %c1 = load volatile i1, i1* %c
     68   br i1 %c1, label %left, label %right
     69 
     70 left:
     71   %val.left = phi i32 [ %val, %guard_block ], [ 50, %merge_block ]
     72   ret i32 %val.left
     73 
     74 right:
     75   %val.right = phi i32 [ %val, %guard_block ], [ 100, %merge_block ]
     76   ret i32 %val.right
     77 
     78 ; CHECK: guard_block:
     79 ; CHECK-NEXT:   call void (i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ]
     80 ; CHECK-NEXT:  unreachable
     81 
     82 ; CHECK: merge_block:
     83 ; CHECK-NEXT:  %c1 = load volatile i1, i1* %c
     84 ; CHECK-NEXT:  [[VAL:%[^ ]]] = select i1 %c1, i32 50, i32 100
     85 ; CHECK-NEXT:  ret i32 [[VAL]]
     86 }
     87