1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
  
     | 
    
      ; RUN: opt %s -S -simplifycfg | FileCheck %s
declare void @foo(i32)
define void @test(i1 %a) {
; CHECK-LABEL: @test
; CHECK: br i1 [[IGNORE:%.*]], label %true, label %false
  switch i1 %a, label %default [i1 1, label %true
                                i1 0, label %false]
true:
  call void @foo(i32 1)
  ret void
false:
  call void @foo(i32 3)
  ret void
default:
  call void @foo(i32 2)
  ret void
}  
define void @test2(i2 %a) {
; CHECK-LABEL: @test2
  switch i2 %a, label %default [i2 0, label %case0
                                i2 1, label %case1
                                i2 2, label %case2
                                i2 3, label %case3]
case0:
  call void @foo(i32 0)
  ret void
case1:
  call void @foo(i32 1)
  ret void
case2:
  call void @foo(i32 2)
  ret void
case3:
  call void @foo(i32 3)
  ret void
default:
; CHECK-LABEL: default1:
; CHECK-NEXT: unreachable
  call void @foo(i32 4)
  ret void
}  
; This one is a negative test - we know the value of the default,
; but that's about it
define void @test3(i2 %a) {
; CHECK-LABEL: @test3
  switch i2 %a, label %default [i2 0, label %case0
                                i2 1, label %case1
                                i2 2, label %case2]
case0:
  call void @foo(i32 0)
  ret void
case1:
  call void @foo(i32 1)
  ret void
case2:
  call void @foo(i32 2)
  ret void
default:
; CHECK-LABEL: default:
; CHECK-NEXT: call void @foo
  call void @foo(i32 0)
  ret void
}  
; Negative test - check for possible overflow when computing
; number of possible cases.
define void @test4(i128 %a) {
; CHECK-LABEL: @test4
  switch i128 %a, label %default [i128 0, label %case0
                                  i128 1, label %case1]
case0:
  call void @foo(i32 0)
  ret void
case1:
  call void @foo(i32 1)
  ret void
default:
; CHECK-LABEL: default:
; CHECK-NEXT: call void @foo
  call void @foo(i32 0)
  ret void
}  
; All but one bit known zero
define void @test5(i8 %a) {
; CHECK-LABEL: @test5
; CHECK: br i1 [[IGNORE:%.*]], label %true, label %false
  %cmp = icmp ult i8 %a, 2 
  call void @llvm.assume(i1 %cmp)
  switch i8 %a, label %default [i8 1, label %true
                                i8 0, label %false]
true:
  call void @foo(i32 1)
  ret void
false:
  call void @foo(i32 3)
  ret void
default:
  call void @foo(i32 2)
  ret void
} 
;; All but one bit known one
define void @test6(i8 %a) {
; CHECK-LABEL: @test6
; CHECK: @llvm.assume
; CHECK: br i1 [[IGNORE:%.*]], label %true, label %false
  %and = and i8 %a, 254
  %cmp = icmp eq i8 %and, 254 
  call void @llvm.assume(i1 %cmp)
  switch i8 %a, label %default [i8 255, label %true
                                i8 254, label %false]
true:
  call void @foo(i32 1)
  ret void
false:
  call void @foo(i32 3)
  ret void
default:
  call void @foo(i32 2)
  ret void
}
; Check that we can eliminate both dead cases and dead defaults
; within a single run of simplify-cfg
define void @test7(i8 %a) {
; CHECK-LABEL: @test7
; CHECK: @llvm.assume
; CHECK: br i1 [[IGNORE:%.*]], label %true, label %false
  %and = and i8 %a, 254
  %cmp = icmp eq i8 %and, 254 
  call void @llvm.assume(i1 %cmp)
  switch i8 %a, label %default [i8 255, label %true
                                i8 254, label %false
                                i8 0, label %also_dead]
true:
  call void @foo(i32 1)
  ret void
false:
  call void @foo(i32 3)
  ret void
also_dead:
  call void @foo(i32 5)
  ret void
default:
  call void @foo(i32 2)
  ret void
}
;; All but one bit known undef
;; Note: This is currently testing an optimization which doesn't trigger. The
;; case this is protecting against is that a bit could be assumed both zero 
;; *or* one given we know it's undef.  ValueTracking doesn't do this today,
;; but it doesn't hurt to confirm.
define void @test8(i8 %a) {
; CHECK-LABEL: @test8(
; CHECK: switch i8
  %and = and i8 %a, 254
  %cmp = icmp eq i8 %and, undef
  call void @llvm.assume(i1 %cmp)
  switch i8 %a, label %default [i8 255, label %true
                                i8 254, label %false]
true:
  call void @foo(i32 1)
  ret void
false:
  call void @foo(i32 3)
  ret void
default:
  call void @foo(i32 2)
  ret void
}
declare void @llvm.assume(i1)
 
     |