1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4; (x << k) ? 2^k * x : 0 --> 2^k * x 5 6define i32 @test_eq(i32 %x) { 7; CHECK-LABEL: @test_eq( 8; CHECK-NEXT: [[MUL:%.*]] = shl i32 [[X:%.*]], 2 9; CHECK-NEXT: ret i32 [[MUL]] 10; 11 %shl.mask = and i32 %x, 1073741823 12 %tobool = icmp eq i32 %shl.mask, 0 13 %mul = shl i32 %x, 2 14 %cond = select i1 %tobool, i32 0, i32 %mul 15 ret i32 %cond 16} 17 18define <2 x i32> @test_eq_vect(<2 x i32> %x) { 19; CHECK-LABEL: @test_eq_vect( 20; CHECK-NEXT: [[MUL:%.*]] = shl <2 x i32> [[X:%.*]], splat (i32 2) 21; CHECK-NEXT: ret <2 x i32> [[MUL]] 22; 23 %shl.mask = and <2 x i32> %x, <i32 1073741823, i32 1073741823> 24 %tobool = icmp eq <2 x i32> %shl.mask, zeroinitializer 25 %mul = shl <2 x i32> %x, <i32 2, i32 2> 26 %cond = select <2 x i1> %tobool, <2 x i32> zeroinitializer, <2 x i32> %mul 27 ret <2 x i32> %cond 28} 29 30define i32 @test_ne(i32 %x) { 31; CHECK-LABEL: @test_ne( 32; CHECK-NEXT: [[MUL:%.*]] = shl i32 [[X:%.*]], 2 33; CHECK-NEXT: ret i32 [[MUL]] 34; 35 %shl.mask = and i32 %x, 1073741823 36 %tobool.not = icmp ne i32 %shl.mask, 0 37 %mul = shl i32 %x, 2 38 %cond = select i1 %tobool.not, i32 %mul, i32 0 39 ret i32 %cond 40} 41 42define <2 x i32> @test_ne_vect(<2 x i32> %x) { 43; CHECK-LABEL: @test_ne_vect( 44; CHECK-NEXT: [[MUL:%.*]] = shl <2 x i32> [[X:%.*]], splat (i32 2) 45; CHECK-NEXT: ret <2 x i32> [[MUL]] 46; 47 %shl.mask = and <2 x i32> %x, <i32 1073741823, i32 1073741823> 48 %tobool.not = icmp ne <2 x i32> %shl.mask, zeroinitializer 49 %mul = shl <2 x i32> %x, <i32 2, i32 2> 50 %cond = select <2 x i1> %tobool.not, <2 x i32> %mul, <2 x i32> zeroinitializer 51 ret <2 x i32> %cond 52} 53 54define i32 @test_nuw_dropped(i32 %x) { 55; CHECK-LABEL: @test_nuw_dropped( 56; CHECK-NEXT: [[MUL:%.*]] = shl i32 [[X:%.*]], 2 57; CHECK-NEXT: ret i32 [[MUL]] 58; 59 %shl.mask = and i32 %x, 1073741823 60 %tobool = icmp eq i32 %shl.mask, 0 61 %mul = shl nuw i32 %x, 2 62 %cond = select i1 %tobool, i32 0, i32 %mul 63 ret i32 %cond 64} 65 66define i32 @test_nsw_dropped(i32 %x) { 67; CHECK-LABEL: @test_nsw_dropped( 68; CHECK-NEXT: [[MUL:%.*]] = shl i32 [[X:%.*]], 2 69; CHECK-NEXT: ret i32 [[MUL]] 70; 71 %shl.mask = and i32 %x, 1073741823 72 %tobool = icmp eq i32 %shl.mask, 0 73 %mul = shl nsw i32 %x, 2 74 %cond = select i1 %tobool, i32 0, i32 %mul 75 ret i32 %cond 76} 77 78declare void @use_multi(i32, i1, i32) 79 80; This will not be canonicalized. 81define i32 @test_multi_use(i32 %x) { 82; CHECK-LABEL: @test_multi_use( 83; CHECK-NEXT: [[SHL_MASK:%.*]] = and i32 [[X:%.*]], 1073741823 84; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp ne i32 [[SHL_MASK]], 0 85; CHECK-NEXT: [[MUL:%.*]] = shl i32 [[X]], 2 86; CHECK-NEXT: call void @use_multi(i32 [[SHL_MASK]], i1 [[TOBOOL_NOT]], i32 [[MUL]]) 87; CHECK-NEXT: ret i32 [[MUL]] 88; 89 %shl.mask = and i32 %x, 1073741823 90 %tobool.not = icmp ne i32 %shl.mask, 0 91 %mul = shl i32 %x, 2 92 %cond = select i1 %tobool.not, i32 %mul, i32 0 93 call void @use_multi(i32 %shl.mask, i1 %tobool.not, i32 %mul) 94 ret i32 %cond 95} 96 97define i32 @test_multi_use_nuw_dropped(i32 %x) { 98; CHECK-LABEL: @test_multi_use_nuw_dropped( 99; CHECK-NEXT: [[SHL_MASK:%.*]] = and i32 [[X:%.*]], 1073741823 100; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[SHL_MASK]], 0 101; CHECK-NEXT: [[MUL:%.*]] = shl i32 [[X]], 2 102; CHECK-NEXT: call void @use_multi(i32 [[SHL_MASK]], i1 [[TOBOOL]], i32 [[MUL]]) 103; CHECK-NEXT: ret i32 [[MUL]] 104; 105 %shl.mask = and i32 %x, 1073741823 106 %tobool = icmp eq i32 %shl.mask, 0 107 %mul = shl nuw i32 %x, 2 108 %cond = select i1 %tobool, i32 0, i32 %mul 109 call void @use_multi(i32 %shl.mask, i1 %tobool, i32 %mul) 110 ret i32 %cond 111} 112 113define i32 @neg_test_bits_not_match(i32 %x) { 114; CHECK-LABEL: @neg_test_bits_not_match( 115; CHECK-NEXT: [[SHL_MASK:%.*]] = and i32 [[X:%.*]], 1073741823 116; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[SHL_MASK]], 0 117; CHECK-NEXT: [[MUL:%.*]] = shl i32 [[X]], 3 118; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 0, i32 [[MUL]] 119; CHECK-NEXT: ret i32 [[COND]] 120; 121 %shl.mask = and i32 %x, 1073741823 122 %tobool = icmp eq i32 %shl.mask, 0 123 %mul = shl i32 %x, 3 124 %cond = select i1 %tobool, i32 0, i32 %mul 125 ret i32 %cond 126} 127 128define i32 @neg_test_icmp_non_equality(i32 %x) { 129; CHECK-LABEL: @neg_test_icmp_non_equality( 130; CHECK-NEXT: [[MUL:%.*]] = shl i32 [[X:%.*]], 2 131; CHECK-NEXT: ret i32 [[MUL]] 132; 133 %shl.mask = and i32 %x, 1073741823 134 %tobool = icmp slt i32 %shl.mask, 0 135 %mul = shl i32 %x, 2 136 %cond = select i1 %tobool, i32 0, i32 %mul 137 ret i32 %cond 138} 139 140define i32 @neg_test_select_non_zero_constant(i32 %x) { 141; CHECK-LABEL: @neg_test_select_non_zero_constant( 142; CHECK-NEXT: [[SHL_MASK:%.*]] = and i32 [[X:%.*]], 1073741823 143; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[SHL_MASK]], 0 144; CHECK-NEXT: [[MUL:%.*]] = shl i32 [[X]], 2 145; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 1, i32 [[MUL]] 146; CHECK-NEXT: ret i32 [[COND]] 147; 148 %shl.mask = and i32 %x, 1073741823 149 %tobool = icmp eq i32 %shl.mask, 0 150 %mul = shl i32 %x, 2 151 %cond = select i1 %tobool, i32 1, i32 %mul 152 ret i32 %cond 153} 154 155define i32 @neg_test_icmp_non_zero_constant(i32 %x) { 156; CHECK-LABEL: @neg_test_icmp_non_zero_constant( 157; CHECK-NEXT: [[SHL_MASK:%.*]] = and i32 [[X:%.*]], 1073741823 158; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[SHL_MASK]], 1 159; CHECK-NEXT: [[MUL:%.*]] = shl i32 [[X]], 2 160; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 0, i32 [[MUL]] 161; CHECK-NEXT: ret i32 [[COND]] 162; 163 %shl.mask = and i32 %x, 1073741823 164 %tobool = icmp eq i32 %shl.mask, 1 165 %mul = shl i32 %x, 2 166 %cond = select i1 %tobool, i32 0, i32 %mul 167 ret i32 %cond 168} 169