1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4define i1 @test_switch_with_shl_mask(i32 %a) { 5; CHECK-LABEL: define i1 @test_switch_with_shl_mask( 6; CHECK-SAME: i32 [[A:%.*]]) { 7; CHECK-NEXT: entry: 8; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[A]] to i8 9; CHECK-NEXT: switch i8 [[TRUNC]], label [[SW_DEFAULT:%.*]] [ 10; CHECK-NEXT: i8 0, label [[SW_BB:%.*]] 11; CHECK-NEXT: i8 1, label [[SW_BB]] 12; CHECK-NEXT: i8 -128, label [[SW_BB]] 13; CHECK-NEXT: ] 14; CHECK: sw.bb: 15; CHECK-NEXT: ret i1 true 16; CHECK: sw.default: 17; CHECK-NEXT: ret i1 false 18; 19entry: 20 %b = shl i32 %a, 24 21 switch i32 %b, label %sw.default [ 22 i32 0, label %sw.bb 23 i32 16777216, label %sw.bb 24 i32 2147483648, label %sw.bb 25 ] 26 27sw.bb: 28 ret i1 true 29sw.default: 30 ret i1 false 31} 32 33define i1 @test_switch_with_shl_nuw_multiuse(i32 %a) { 34; CHECK-LABEL: define i1 @test_switch_with_shl_nuw_multiuse( 35; CHECK-SAME: i32 [[A:%.*]]) { 36; CHECK-NEXT: entry: 37; CHECK-NEXT: [[B:%.*]] = shl nuw i32 [[A]], 24 38; CHECK-NEXT: call void @use(i32 [[B]]) 39; CHECK-NEXT: switch i32 [[A]], label [[SW_DEFAULT:%.*]] [ 40; CHECK-NEXT: i32 0, label [[SW_BB:%.*]] 41; CHECK-NEXT: i32 1, label [[SW_BB]] 42; CHECK-NEXT: i32 128, label [[SW_BB]] 43; CHECK-NEXT: ] 44; CHECK: sw.bb: 45; CHECK-NEXT: ret i1 true 46; CHECK: sw.default: 47; CHECK-NEXT: ret i1 false 48; 49entry: 50 %b = shl nuw i32 %a, 24 51 call void @use(i32 %b) 52 switch i32 %b, label %sw.default [ 53 i32 0, label %sw.bb 54 i32 16777216, label %sw.bb 55 i32 2147483648, label %sw.bb 56 ] 57 58sw.bb: 59 ret i1 true 60sw.default: 61 ret i1 false 62} 63 64define i1 @test_switch_with_shl_nsw_multiuse(i32 %a) { 65; CHECK-LABEL: define i1 @test_switch_with_shl_nsw_multiuse( 66; CHECK-SAME: i32 [[A:%.*]]) { 67; CHECK-NEXT: entry: 68; CHECK-NEXT: [[B:%.*]] = shl nsw i32 [[A]], 24 69; CHECK-NEXT: call void @use(i32 [[B]]) 70; CHECK-NEXT: switch i32 [[A]], label [[SW_DEFAULT:%.*]] [ 71; CHECK-NEXT: i32 0, label [[SW_BB:%.*]] 72; CHECK-NEXT: i32 1, label [[SW_BB]] 73; CHECK-NEXT: i32 -128, label [[SW_BB]] 74; CHECK-NEXT: ] 75; CHECK: sw.bb: 76; CHECK-NEXT: ret i1 true 77; CHECK: sw.default: 78; CHECK-NEXT: ret i1 false 79; 80entry: 81 %b = shl nsw i32 %a, 24 82 call void @use(i32 %b) 83 switch i32 %b, label %sw.default [ 84 i32 0, label %sw.bb 85 i32 16777216, label %sw.bb 86 i32 2147483648, label %sw.bb 87 ] 88 89sw.bb: 90 ret i1 true 91sw.default: 92 ret i1 false 93} 94 95; Negative tests 96 97define i1 @test_switch_with_shl_mask_multiuse(i32 %a) { 98; CHECK-LABEL: define i1 @test_switch_with_shl_mask_multiuse( 99; CHECK-SAME: i32 [[A:%.*]]) { 100; CHECK-NEXT: entry: 101; CHECK-NEXT: [[B:%.*]] = shl i32 [[A]], 24 102; CHECK-NEXT: call void @use(i32 [[B]]) 103; CHECK-NEXT: switch i32 [[B]], label [[SW_DEFAULT:%.*]] [ 104; CHECK-NEXT: i32 0, label [[SW_BB:%.*]] 105; CHECK-NEXT: i32 16777216, label [[SW_BB]] 106; CHECK-NEXT: i32 -2147483648, label [[SW_BB]] 107; CHECK-NEXT: ] 108; CHECK: sw.bb: 109; CHECK-NEXT: ret i1 true 110; CHECK: sw.default: 111; CHECK-NEXT: ret i1 false 112; 113entry: 114 %b = shl i32 %a, 24 115 call void @use(i32 %b) 116 switch i32 %b, label %sw.default [ 117 i32 0, label %sw.bb 118 i32 16777216, label %sw.bb 119 i32 2147483648, label %sw.bb 120 ] 121 122sw.bb: 123 ret i1 true 124sw.default: 125 ret i1 false 126} 127 128define i1 @test_switch_with_shl_mask_unknown_shamt(i32 %a, i32 %shamt) { 129; CHECK-LABEL: define i1 @test_switch_with_shl_mask_unknown_shamt( 130; CHECK-SAME: i32 [[A:%.*]], i32 [[SHAMT:%.*]]) { 131; CHECK-NEXT: entry: 132; CHECK-NEXT: [[B:%.*]] = shl i32 [[A]], [[SHAMT]] 133; CHECK-NEXT: switch i32 [[B]], label [[SW_DEFAULT:%.*]] [ 134; CHECK-NEXT: i32 0, label [[SW_BB:%.*]] 135; CHECK-NEXT: i32 16777216, label [[SW_BB]] 136; CHECK-NEXT: i32 -2147483648, label [[SW_BB]] 137; CHECK-NEXT: ] 138; CHECK: sw.bb: 139; CHECK-NEXT: ret i1 true 140; CHECK: sw.default: 141; CHECK-NEXT: ret i1 false 142; 143entry: 144 %b = shl i32 %a, %shamt 145 switch i32 %b, label %sw.default [ 146 i32 0, label %sw.bb 147 i32 16777216, label %sw.bb 148 i32 2147483648, label %sw.bb 149 ] 150 151sw.bb: 152 ret i1 true 153sw.default: 154 ret i1 false 155} 156 157define i1 @test_switch_with_shl_mask_poison(i32 %a) { 158; CHECK-LABEL: define i1 @test_switch_with_shl_mask_poison( 159; CHECK-SAME: i32 [[A:%.*]]) { 160; CHECK-NEXT: entry: 161; CHECK-NEXT: switch i32 poison, label [[SW_DEFAULT:%.*]] [ 162; CHECK-NEXT: i32 0, label [[SW_BB:%.*]] 163; CHECK-NEXT: i32 16777216, label [[SW_BB]] 164; CHECK-NEXT: i32 -2147483648, label [[SW_BB]] 165; CHECK-NEXT: ] 166; CHECK: sw.bb: 167; CHECK-NEXT: ret i1 true 168; CHECK: sw.default: 169; CHECK-NEXT: ret i1 false 170; 171entry: 172 %b = shl i32 %a, 32 173 switch i32 %b, label %sw.default [ 174 i32 0, label %sw.bb 175 i32 16777216, label %sw.bb 176 i32 2147483648, label %sw.bb 177 ] 178 179sw.bb: 180 ret i1 true 181sw.default: 182 ret i1 false 183} 184 185declare void @use(i32) 186