1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -instcombine -S | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Workerdefine i64 @test1(i64 %A, i32 %B) { 4*9880d681SAndroid Build Coastguard Worker %tmp12 = zext i32 %B to i64 5*9880d681SAndroid Build Coastguard Worker %tmp3 = shl i64 %tmp12, 32 6*9880d681SAndroid Build Coastguard Worker %tmp5 = add i64 %tmp3, %A 7*9880d681SAndroid Build Coastguard Worker %tmp6 = and i64 %tmp5, 123 8*9880d681SAndroid Build Coastguard Worker ret i64 %tmp6 9*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test1( 10*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: and i64 %A, 123 11*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i64 12*9880d681SAndroid Build Coastguard Worker} 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Workerdefine i32 @test2(i32 %A) { 15*9880d681SAndroid Build Coastguard Worker %B = and i32 %A, 7 16*9880d681SAndroid Build Coastguard Worker %C = and i32 %A, 32 17*9880d681SAndroid Build Coastguard Worker %F = add i32 %B, %C 18*9880d681SAndroid Build Coastguard Worker ret i32 %F 19*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test2( 20*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: and i32 %A, 39 21*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 22*9880d681SAndroid Build Coastguard Worker} 23*9880d681SAndroid Build Coastguard Worker 24*9880d681SAndroid Build Coastguard Workerdefine i32 @test3(i32 %A) { 25*9880d681SAndroid Build Coastguard Worker %B = and i32 %A, 128 26*9880d681SAndroid Build Coastguard Worker %C = lshr i32 %A, 30 27*9880d681SAndroid Build Coastguard Worker %F = add i32 %B, %C 28*9880d681SAndroid Build Coastguard Worker ret i32 %F 29*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test3( 30*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: and 31*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lshr 32*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: or i32 %B, %C 33*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 34*9880d681SAndroid Build Coastguard Worker} 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Workerdefine i32 @test4(i32 %A) { 37*9880d681SAndroid Build Coastguard Worker %B = add nuw i32 %A, %A 38*9880d681SAndroid Build Coastguard Worker ret i32 %B 39*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test4( 40*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %B = shl nuw i32 %A, 1 41*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 %B 42*9880d681SAndroid Build Coastguard Worker} 43*9880d681SAndroid Build Coastguard Worker 44*9880d681SAndroid Build Coastguard Workerdefine <2 x i1> @test5(<2 x i1> %A, <2 x i1> %B) { 45*9880d681SAndroid Build Coastguard Worker %add = add <2 x i1> %A, %B 46*9880d681SAndroid Build Coastguard Worker ret <2 x i1> %add 47*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test5( 48*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %add = xor <2 x i1> %A, %B 49*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret <2 x i1> %add 50*9880d681SAndroid Build Coastguard Worker} 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Workerdefine <2 x i64> @test6(<2 x i64> %A) { 53*9880d681SAndroid Build Coastguard Worker %shl = shl <2 x i64> %A, <i64 2, i64 3> 54*9880d681SAndroid Build Coastguard Worker %add = add <2 x i64> %shl, %A 55*9880d681SAndroid Build Coastguard Worker ret <2 x i64> %add 56*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test6( 57*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %add = mul <2 x i64> %A, <i64 5, i64 9> 58*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret <2 x i64> %add 59*9880d681SAndroid Build Coastguard Worker} 60*9880d681SAndroid Build Coastguard Worker 61*9880d681SAndroid Build Coastguard Workerdefine <2 x i64> @test7(<2 x i64> %A) { 62*9880d681SAndroid Build Coastguard Worker %shl = shl <2 x i64> %A, <i64 2, i64 3> 63*9880d681SAndroid Build Coastguard Worker %mul = mul <2 x i64> %A, <i64 3, i64 4> 64*9880d681SAndroid Build Coastguard Worker %add = add <2 x i64> %shl, %mul 65*9880d681SAndroid Build Coastguard Worker ret <2 x i64> %add 66*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test7( 67*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %add = mul <2 x i64> %A, <i64 7, i64 12> 68*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret <2 x i64> %add 69*9880d681SAndroid Build Coastguard Worker} 70*9880d681SAndroid Build Coastguard Worker 71*9880d681SAndroid Build Coastguard Workerdefine <2 x i64> @test8(<2 x i64> %A) { 72*9880d681SAndroid Build Coastguard Worker %xor = xor <2 x i64> %A, <i64 -1, i64 -1> 73*9880d681SAndroid Build Coastguard Worker %add = add <2 x i64> %xor, <i64 2, i64 3> 74*9880d681SAndroid Build Coastguard Worker ret <2 x i64> %add 75*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test8( 76*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %add = sub <2 x i64> <i64 1, i64 2>, %A 77*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret <2 x i64> %add 78*9880d681SAndroid Build Coastguard Worker} 79*9880d681SAndroid Build Coastguard Worker 80*9880d681SAndroid Build Coastguard Workerdefine i16 @test9(i16 %a) { 81*9880d681SAndroid Build Coastguard Worker %b = mul i16 %a, 2 82*9880d681SAndroid Build Coastguard Worker %c = mul i16 %a, 32767 83*9880d681SAndroid Build Coastguard Worker %d = add i16 %b, %c 84*9880d681SAndroid Build Coastguard Worker ret i16 %d 85*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test9( 86*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %d = mul i16 %a, -32767 87*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i16 %d 88*9880d681SAndroid Build Coastguard Worker} 89*9880d681SAndroid Build Coastguard Worker 90*9880d681SAndroid Build Coastguard Worker; y + (~((x >> 3) & 0x55555555) + 1) -> y - ((x >> 3) & 0x55555555) 91*9880d681SAndroid Build Coastguard Workerdefine i32 @test10(i32 %x, i32 %y) { 92*9880d681SAndroid Build Coastguard Worker %shr = ashr i32 %x, 3 93*9880d681SAndroid Build Coastguard Worker %shr.not = or i32 %shr, -1431655766 94*9880d681SAndroid Build Coastguard Worker %neg = xor i32 %shr.not, 1431655765 95*9880d681SAndroid Build Coastguard Worker %add = add i32 %y, 1 96*9880d681SAndroid Build Coastguard Worker %add1 = add i32 %add, %neg 97*9880d681SAndroid Build Coastguard Worker ret i32 %add1 98*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test10( 99*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[SHR:%[a-z0-9]+]] = ashr i32 %x, 3 100*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 [[SHR]], 1431655765 101*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]] 102*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 [[SUB]] 103*9880d681SAndroid Build Coastguard Worker} 104*9880d681SAndroid Build Coastguard Worker 105*9880d681SAndroid Build Coastguard Worker; y + (~(x & 0x55555555) + 1) -> y - (x & 0x55555555) 106*9880d681SAndroid Build Coastguard Workerdefine i32 @test11(i32 %x, i32 %y) { 107*9880d681SAndroid Build Coastguard Worker %x.not = or i32 %x, -1431655766 108*9880d681SAndroid Build Coastguard Worker %neg = xor i32 %x.not, 1431655765 109*9880d681SAndroid Build Coastguard Worker %add = add i32 %y, 1 110*9880d681SAndroid Build Coastguard Worker %add1 = add i32 %add, %neg 111*9880d681SAndroid Build Coastguard Worker ret i32 %add1 112*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test11( 113*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, 1431655765 114*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]] 115*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 [[SUB]] 116*9880d681SAndroid Build Coastguard Worker} 117*9880d681SAndroid Build Coastguard Worker 118*9880d681SAndroid Build Coastguard Worker; (y + 1) + ~(x & 0x55555555) -> y - (x & 0x55555555) 119*9880d681SAndroid Build Coastguard Workerdefine i32 @test12(i32 %x, i32 %y) { 120*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %y, 1 121*9880d681SAndroid Build Coastguard Worker %x.not = or i32 %x, -1431655766 122*9880d681SAndroid Build Coastguard Worker %neg = xor i32 %x.not, 1431655765 123*9880d681SAndroid Build Coastguard Worker %add1 = add nsw i32 %add, %neg 124*9880d681SAndroid Build Coastguard Worker ret i32 %add1 125*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test12( 126*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, 1431655765 127*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]] 128*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 [[SUB]] 129*9880d681SAndroid Build Coastguard Worker} 130*9880d681SAndroid Build Coastguard Worker 131*9880d681SAndroid Build Coastguard Worker; y + (~(x & 0x55555556) + 1) -> y - (x & 0x55555556) 132*9880d681SAndroid Build Coastguard Workerdefine i32 @test13(i32 %x, i32 %y) { 133*9880d681SAndroid Build Coastguard Worker %x.not = or i32 %x, -1431655767 134*9880d681SAndroid Build Coastguard Worker %neg = xor i32 %x.not, 1431655766 135*9880d681SAndroid Build Coastguard Worker %add = add i32 %y, 1 136*9880d681SAndroid Build Coastguard Worker %add1 = add i32 %add, %neg 137*9880d681SAndroid Build Coastguard Worker ret i32 %add1 138*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test13( 139*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, 1431655766 140*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]] 141*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 [[SUB]] 142*9880d681SAndroid Build Coastguard Worker} 143*9880d681SAndroid Build Coastguard Worker 144*9880d681SAndroid Build Coastguard Worker; (y + 1) + ~(x & 0x55555556) -> y - (x & 0x55555556) 145*9880d681SAndroid Build Coastguard Workerdefine i32 @test14(i32 %x, i32 %y) { 146*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %y, 1 147*9880d681SAndroid Build Coastguard Worker %x.not = or i32 %x, -1431655767 148*9880d681SAndroid Build Coastguard Worker %neg = xor i32 %x.not, 1431655766 149*9880d681SAndroid Build Coastguard Worker %add1 = add nsw i32 %add, %neg 150*9880d681SAndroid Build Coastguard Worker ret i32 %add1 151*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test14( 152*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, 1431655766 153*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]] 154*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 [[SUB]] 155*9880d681SAndroid Build Coastguard Worker} 156*9880d681SAndroid Build Coastguard Worker 157*9880d681SAndroid Build Coastguard Worker; y + (~(x | 0x55555556) + 1) -> y - (x | 0x55555556) 158*9880d681SAndroid Build Coastguard Workerdefine i32 @test15(i32 %x, i32 %y) { 159*9880d681SAndroid Build Coastguard Worker %x.not = and i32 %x, -1431655767 160*9880d681SAndroid Build Coastguard Worker %neg = xor i32 %x.not, -1431655767 161*9880d681SAndroid Build Coastguard Worker %add = add i32 %y, 1 162*9880d681SAndroid Build Coastguard Worker %add1 = add i32 %add, %neg 163*9880d681SAndroid Build Coastguard Worker ret i32 %add1 164*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test15( 165*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[AND:%[a-z0-9]+]] = or i32 %x, 1431655766 166*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]] 167*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 [[SUB]] 168*9880d681SAndroid Build Coastguard Worker} 169*9880d681SAndroid Build Coastguard Worker 170*9880d681SAndroid Build Coastguard Worker; (y + 1) + ~(x | 0x55555556) -> y - (x | 0x555555556) 171*9880d681SAndroid Build Coastguard Workerdefine i32 @test16(i32 %x, i32 %y) { 172*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %y, 1 173*9880d681SAndroid Build Coastguard Worker %x.not = and i32 %x, -1431655767 174*9880d681SAndroid Build Coastguard Worker %neg = xor i32 %x.not, -1431655767 175*9880d681SAndroid Build Coastguard Worker %add1 = add nsw i32 %add, %neg 176*9880d681SAndroid Build Coastguard Worker ret i32 %add1 177*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test16( 178*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[AND:%[a-z0-9]+]] = or i32 %x, 1431655766 179*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]] 180*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 [[SUB]] 181*9880d681SAndroid Build Coastguard Worker} 182*9880d681SAndroid Build Coastguard Worker 183*9880d681SAndroid Build Coastguard Worker; y + (~(x | 0x55555555) + 1) -> y - (x | 0x55555555) 184*9880d681SAndroid Build Coastguard Workerdefine i32 @test17(i32 %x, i32 %y) { 185*9880d681SAndroid Build Coastguard Worker %x.not = and i32 %x, -1431655766 186*9880d681SAndroid Build Coastguard Worker %add2 = xor i32 %x.not, -1431655765 187*9880d681SAndroid Build Coastguard Worker %add1 = add nsw i32 %add2, %y 188*9880d681SAndroid Build Coastguard Worker ret i32 %add1 189*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test17( 190*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[AND:%[a-z0-9]+]] = or i32 %x, 1431655765 191*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]] 192*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 [[SUB]] 193*9880d681SAndroid Build Coastguard Worker} 194*9880d681SAndroid Build Coastguard Worker 195*9880d681SAndroid Build Coastguard Worker; (y + 1) + ~(x | 0x55555555) -> y - (x | 0x55555555) 196*9880d681SAndroid Build Coastguard Workerdefine i32 @test18(i32 %x, i32 %y) { 197*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %y, 1 198*9880d681SAndroid Build Coastguard Worker %x.not = and i32 %x, -1431655766 199*9880d681SAndroid Build Coastguard Worker %neg = xor i32 %x.not, -1431655766 200*9880d681SAndroid Build Coastguard Worker %add1 = add nsw i32 %add, %neg 201*9880d681SAndroid Build Coastguard Worker ret i32 %add1 202*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test18( 203*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[AND:%[a-z0-9]+]] = or i32 %x, 1431655765 204*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]] 205*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 [[SUB]] 206*9880d681SAndroid Build Coastguard Worker} 207*9880d681SAndroid Build Coastguard Worker 208*9880d681SAndroid Build Coastguard Workerdefine i16 @add_nsw_mul_nsw(i16 %x) { 209*9880d681SAndroid Build Coastguard Worker %add1 = add nsw i16 %x, %x 210*9880d681SAndroid Build Coastguard Worker %add2 = add nsw i16 %add1, %x 211*9880d681SAndroid Build Coastguard Worker ret i16 %add2 212*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @add_nsw_mul_nsw( 213*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %add2 = mul nsw i16 %x, 3 214*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i16 %add2 215*9880d681SAndroid Build Coastguard Worker} 216*9880d681SAndroid Build Coastguard Worker 217*9880d681SAndroid Build Coastguard Workerdefine i16 @mul_add_to_mul_1(i16 %x) { 218*9880d681SAndroid Build Coastguard Worker %mul1 = mul nsw i16 %x, 8 219*9880d681SAndroid Build Coastguard Worker %add2 = add nsw i16 %x, %mul1 220*9880d681SAndroid Build Coastguard Worker ret i16 %add2 221*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @mul_add_to_mul_1( 222*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %add2 = mul nsw i16 %x, 9 223*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i16 %add2 224*9880d681SAndroid Build Coastguard Worker} 225*9880d681SAndroid Build Coastguard Worker 226*9880d681SAndroid Build Coastguard Workerdefine i16 @mul_add_to_mul_2(i16 %x) { 227*9880d681SAndroid Build Coastguard Worker %mul1 = mul nsw i16 %x, 8 228*9880d681SAndroid Build Coastguard Worker %add2 = add nsw i16 %mul1, %x 229*9880d681SAndroid Build Coastguard Worker ret i16 %add2 230*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @mul_add_to_mul_2( 231*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %add2 = mul nsw i16 %x, 9 232*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i16 %add2 233*9880d681SAndroid Build Coastguard Worker} 234*9880d681SAndroid Build Coastguard Worker 235*9880d681SAndroid Build Coastguard Workerdefine i16 @mul_add_to_mul_3(i16 %a) { 236*9880d681SAndroid Build Coastguard Worker %mul1 = mul i16 %a, 2 237*9880d681SAndroid Build Coastguard Worker %mul2 = mul i16 %a, 3 238*9880d681SAndroid Build Coastguard Worker %add = add nsw i16 %mul1, %mul2 239*9880d681SAndroid Build Coastguard Worker ret i16 %add 240*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @mul_add_to_mul_3( 241*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %add = mul i16 %a, 5 242*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i16 %add 243*9880d681SAndroid Build Coastguard Worker} 244*9880d681SAndroid Build Coastguard Worker 245*9880d681SAndroid Build Coastguard Workerdefine i16 @mul_add_to_mul_4(i16 %a) { 246*9880d681SAndroid Build Coastguard Worker %mul1 = mul nsw i16 %a, 2 247*9880d681SAndroid Build Coastguard Worker %mul2 = mul nsw i16 %a, 7 248*9880d681SAndroid Build Coastguard Worker %add = add nsw i16 %mul1, %mul2 249*9880d681SAndroid Build Coastguard Worker ret i16 %add 250*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @mul_add_to_mul_4( 251*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %add = mul nsw i16 %a, 9 252*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i16 %add 253*9880d681SAndroid Build Coastguard Worker} 254*9880d681SAndroid Build Coastguard Worker 255*9880d681SAndroid Build Coastguard Workerdefine i16 @mul_add_to_mul_5(i16 %a) { 256*9880d681SAndroid Build Coastguard Worker %mul1 = mul nsw i16 %a, 3 257*9880d681SAndroid Build Coastguard Worker %mul2 = mul nsw i16 %a, 7 258*9880d681SAndroid Build Coastguard Worker %add = add nsw i16 %mul1, %mul2 259*9880d681SAndroid Build Coastguard Worker ret i16 %add 260*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @mul_add_to_mul_5( 261*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %add = mul nsw i16 %a, 10 262*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i16 %add 263*9880d681SAndroid Build Coastguard Worker} 264*9880d681SAndroid Build Coastguard Worker 265*9880d681SAndroid Build Coastguard Workerdefine i32 @mul_add_to_mul_6(i32 %x, i32 %y) { 266*9880d681SAndroid Build Coastguard Worker %mul1 = mul nsw i32 %x, %y 267*9880d681SAndroid Build Coastguard Worker %mul2 = mul nsw i32 %mul1, 5 268*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %mul1, %mul2 269*9880d681SAndroid Build Coastguard Worker ret i32 %add 270*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @mul_add_to_mul_6( 271*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %mul1 = mul nsw i32 %x, %y 272*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %add = mul nsw i32 %mul1, 6 273*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 %add 274*9880d681SAndroid Build Coastguard Worker} 275*9880d681SAndroid Build Coastguard Worker 276*9880d681SAndroid Build Coastguard Workerdefine i16 @mul_add_to_mul_7(i16 %x) { 277*9880d681SAndroid Build Coastguard Worker %mul1 = mul nsw i16 %x, 32767 278*9880d681SAndroid Build Coastguard Worker %add2 = add nsw i16 %x, %mul1 279*9880d681SAndroid Build Coastguard Worker ret i16 %add2 280*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @mul_add_to_mul_7( 281*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %add2 = shl i16 %x, 15 282*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i16 %add2 283*9880d681SAndroid Build Coastguard Worker} 284*9880d681SAndroid Build Coastguard Worker 285*9880d681SAndroid Build Coastguard Workerdefine i16 @mul_add_to_mul_8(i16 %a) { 286*9880d681SAndroid Build Coastguard Worker %mul1 = mul nsw i16 %a, 16383 287*9880d681SAndroid Build Coastguard Worker %mul2 = mul nsw i16 %a, 16384 288*9880d681SAndroid Build Coastguard Worker %add = add nsw i16 %mul1, %mul2 289*9880d681SAndroid Build Coastguard Worker ret i16 %add 290*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @mul_add_to_mul_8( 291*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %add = mul nsw i16 %a, 32767 292*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i16 %add 293*9880d681SAndroid Build Coastguard Worker} 294*9880d681SAndroid Build Coastguard Worker 295*9880d681SAndroid Build Coastguard Workerdefine i16 @mul_add_to_mul_9(i16 %a) { 296*9880d681SAndroid Build Coastguard Worker %mul1 = mul nsw i16 %a, 16384 297*9880d681SAndroid Build Coastguard Worker %mul2 = mul nsw i16 %a, 16384 298*9880d681SAndroid Build Coastguard Worker %add = add nsw i16 %mul1, %mul2 299*9880d681SAndroid Build Coastguard Worker ret i16 %add 300*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @mul_add_to_mul_9( 301*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %add = shl i16 %a, 15 302*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i16 %add 303*9880d681SAndroid Build Coastguard Worker} 304*9880d681SAndroid Build Coastguard Worker 305*9880d681SAndroid Build Coastguard Worker; This test and the next test verify that when a range metadata is attached to 306*9880d681SAndroid Build Coastguard Worker; llvm.cttz, ValueTracking correctly intersects the range specified by the 307*9880d681SAndroid Build Coastguard Worker; metadata and the range implied by the intrinsic. 308*9880d681SAndroid Build Coastguard Worker; 309*9880d681SAndroid Build Coastguard Worker; In this test, the range specified by the metadata is more strict. Therefore, 310*9880d681SAndroid Build Coastguard Worker; ValueTracking uses that range. 311*9880d681SAndroid Build Coastguard Workerdefine i16 @add_cttz(i16 %a) { 312*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @add_cttz( 313*9880d681SAndroid Build Coastguard Worker ; llvm.cttz.i16(..., /*is_zero_undefined=*/true) implies the value returned 314*9880d681SAndroid Build Coastguard Worker ; is in [0, 16). The range metadata indicates the value returned is in [0, 8). 315*9880d681SAndroid Build Coastguard Worker ; Intersecting these ranges, we know the value returned is in [0, 8). 316*9880d681SAndroid Build Coastguard Worker ; Therefore, InstCombine will transform 317*9880d681SAndroid Build Coastguard Worker ; add %cttz, 1111 1111 1111 1000 ; decimal -8 318*9880d681SAndroid Build Coastguard Worker ; to 319*9880d681SAndroid Build Coastguard Worker ; or %cttz, 1111 1111 1111 1000 320*9880d681SAndroid Build Coastguard Worker %cttz = call i16 @llvm.cttz.i16(i16 %a, i1 true), !range !0 321*9880d681SAndroid Build Coastguard Worker %b = add i16 %cttz, -8 322*9880d681SAndroid Build Coastguard Worker; CHECK: or i16 %cttz, -8 323*9880d681SAndroid Build Coastguard Worker ret i16 %b 324*9880d681SAndroid Build Coastguard Worker} 325*9880d681SAndroid Build Coastguard Workerdeclare i16 @llvm.cttz.i16(i16, i1) 326*9880d681SAndroid Build Coastguard Worker!0 = !{i16 0, i16 8} 327*9880d681SAndroid Build Coastguard Worker 328*9880d681SAndroid Build Coastguard Worker; Similar to @add_cttz, but in this test, the range implied by the 329*9880d681SAndroid Build Coastguard Worker; intrinsic is more strict. Therefore, ValueTracking uses that range. 330*9880d681SAndroid Build Coastguard Workerdefine i16 @add_cttz_2(i16 %a) { 331*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @add_cttz_2( 332*9880d681SAndroid Build Coastguard Worker ; llvm.cttz.i16(..., /*is_zero_undefined=*/true) implies the value returned 333*9880d681SAndroid Build Coastguard Worker ; is in [0, 16). The range metadata indicates the value returned is in 334*9880d681SAndroid Build Coastguard Worker ; [0, 32). Intersecting these ranges, we know the value returned is in 335*9880d681SAndroid Build Coastguard Worker ; [0, 16). Therefore, InstCombine will transform 336*9880d681SAndroid Build Coastguard Worker ; add %cttz, 1111 1111 1111 0000 ; decimal -16 337*9880d681SAndroid Build Coastguard Worker ; to 338*9880d681SAndroid Build Coastguard Worker ; or %cttz, 1111 1111 1111 0000 339*9880d681SAndroid Build Coastguard Worker %cttz = call i16 @llvm.cttz.i16(i16 %a, i1 true), !range !1 340*9880d681SAndroid Build Coastguard Worker %b = add i16 %cttz, -16 341*9880d681SAndroid Build Coastguard Worker; CHECK: or i16 %cttz, -16 342*9880d681SAndroid Build Coastguard Worker ret i16 %b 343*9880d681SAndroid Build Coastguard Worker} 344*9880d681SAndroid Build Coastguard Worker!1 = !{i16 0, i16 32} 345*9880d681SAndroid Build Coastguard Worker 346*9880d681SAndroid Build Coastguard Workerdefine i32 @add_or_and(i32 %x, i32 %y) { 347*9880d681SAndroid Build Coastguard Worker %or = or i32 %x, %y 348*9880d681SAndroid Build Coastguard Worker %and = and i32 %x, %y 349*9880d681SAndroid Build Coastguard Worker %add = add i32 %or, %and 350*9880d681SAndroid Build Coastguard Worker ret i32 %add 351*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @add_or_and( 352*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add i32 %x, %y 353*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 354*9880d681SAndroid Build Coastguard Worker} 355*9880d681SAndroid Build Coastguard Worker 356*9880d681SAndroid Build Coastguard Workerdefine i32 @add_nsw_or_and(i32 %x, i32 %y) { 357*9880d681SAndroid Build Coastguard Worker %or = or i32 %x, %y 358*9880d681SAndroid Build Coastguard Worker %and = and i32 %x, %y 359*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %or, %and 360*9880d681SAndroid Build Coastguard Worker ret i32 %add 361*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @add_nsw_or_and( 362*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add nsw i32 %x, %y 363*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 364*9880d681SAndroid Build Coastguard Worker} 365*9880d681SAndroid Build Coastguard Worker 366*9880d681SAndroid Build Coastguard Workerdefine i32 @add_nuw_or_and(i32 %x, i32 %y) { 367*9880d681SAndroid Build Coastguard Worker %or = or i32 %x, %y 368*9880d681SAndroid Build Coastguard Worker %and = and i32 %x, %y 369*9880d681SAndroid Build Coastguard Worker %add = add nuw i32 %or, %and 370*9880d681SAndroid Build Coastguard Worker ret i32 %add 371*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @add_nuw_or_and( 372*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add nuw i32 %x, %y 373*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 374*9880d681SAndroid Build Coastguard Worker} 375*9880d681SAndroid Build Coastguard Worker 376*9880d681SAndroid Build Coastguard Workerdefine i32 @add_nuw_nsw_or_and(i32 %x, i32 %y) { 377*9880d681SAndroid Build Coastguard Worker %or = or i32 %x, %y 378*9880d681SAndroid Build Coastguard Worker %and = and i32 %x, %y 379*9880d681SAndroid Build Coastguard Worker %add = add nsw nuw i32 %or, %and 380*9880d681SAndroid Build Coastguard Worker ret i32 %add 381*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @add_nuw_nsw_or_and( 382*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add nuw nsw i32 %x, %y 383*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 384*9880d681SAndroid Build Coastguard Worker} 385*9880d681SAndroid Build Coastguard Worker 386*9880d681SAndroid Build Coastguard Worker; A *nsw B + A *nsw C != A *nsw (B + C) 387*9880d681SAndroid Build Coastguard Worker; e.g. A = -1, B = 1, C = INT_SMAX 388*9880d681SAndroid Build Coastguard Worker 389*9880d681SAndroid Build Coastguard Workerdefine i8 @add_of_mul(i8 %x, i8 %y, i8 %z) { 390*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @add_of_mul( 391*9880d681SAndroid Build Coastguard Worker entry: 392*9880d681SAndroid Build Coastguard Worker %mA = mul nsw i8 %x, %y 393*9880d681SAndroid Build Coastguard Worker %mB = mul nsw i8 %x, %z 394*9880d681SAndroid Build Coastguard Worker; CHECK: %sum = mul i8 395*9880d681SAndroid Build Coastguard Worker %sum = add nsw i8 %mA, %mB 396*9880d681SAndroid Build Coastguard Worker ret i8 %sum 397*9880d681SAndroid Build Coastguard Worker} 398*9880d681SAndroid Build Coastguard Worker 399*9880d681SAndroid Build Coastguard Workerdefine i32 @add_of_selects(i1 %A, i32 %B) { 400*9880d681SAndroid Build Coastguard Worker %sel0 = select i1 %A, i32 0, i32 -2 401*9880d681SAndroid Build Coastguard Worker %sel1 = select i1 %A, i32 %B, i32 2 402*9880d681SAndroid Build Coastguard Worker %add = add i32 %sel0, %sel1 403*9880d681SAndroid Build Coastguard Worker ret i32 %add 404*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @add_of_selects( 405*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %[[sel:.*]] = select i1 %A, i32 %B, i32 0 406*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 %[[sel]] 407*9880d681SAndroid Build Coastguard Worker} 408