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