1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -S -passes=instcombine | FileCheck %s 3 4declare i32 @llvm.cttz.i32(i32, i1) 5declare i32 @llvm.ctlz.i32(i32, i1) 6declare <2 x i64> @llvm.cttz.v2i64(<2 x i64>, i1) 7declare void @use(i32) 8 9define i32 @cttz_zext_zero_undef(i16 %x) { 10; CHECK-LABEL: @cttz_zext_zero_undef( 11; CHECK-NEXT: [[TMP1:%.*]] = call range(i16 0, 17) i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 true) 12; CHECK-NEXT: [[TZ:%.*]] = zext nneg i16 [[TMP1]] to i32 13; CHECK-NEXT: ret i32 [[TZ]] 14; 15 %z = zext i16 %x to i32 16 %tz = call i32 @llvm.cttz.i32(i32 %z, i1 true) 17 ret i32 %tz 18} 19 20define i32 @cttz_zext_zero_def(i16 %x) { 21; CHECK-LABEL: @cttz_zext_zero_def( 22; CHECK-NEXT: [[Z:%.*]] = zext i16 [[X:%.*]] to i32 23; CHECK-NEXT: [[TZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[Z]], i1 false) 24; CHECK-NEXT: ret i32 [[TZ]] 25; 26 %z = zext i16 %x to i32 27 %tz = call i32 @llvm.cttz.i32(i32 %z, i1 false) 28 ret i32 %tz 29} 30 31define i32 @cttz_zext_zero_undef_extra_use(i16 %x) { 32; CHECK-LABEL: @cttz_zext_zero_undef_extra_use( 33; CHECK-NEXT: [[Z:%.*]] = zext i16 [[X:%.*]] to i32 34; CHECK-NEXT: call void @use(i32 [[Z]]) 35; CHECK-NEXT: [[TZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[Z]], i1 true) 36; CHECK-NEXT: ret i32 [[TZ]] 37; 38 %z = zext i16 %x to i32 39 call void @use(i32 %z) 40 %tz = call i32 @llvm.cttz.i32(i32 %z, i1 true) 41 ret i32 %tz 42} 43 44define <2 x i64> @cttz_zext_zero_undef_vec(<2 x i32> %x) { 45; CHECK-LABEL: @cttz_zext_zero_undef_vec( 46; CHECK-NEXT: [[TMP1:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[X:%.*]], i1 true) 47; CHECK-NEXT: [[TZ:%.*]] = zext nneg <2 x i32> [[TMP1]] to <2 x i64> 48; CHECK-NEXT: ret <2 x i64> [[TZ]] 49; 50 %z = zext <2 x i32> %x to <2 x i64> 51 %tz = tail call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %z, i1 true) 52 ret <2 x i64> %tz 53} 54 55define <2 x i64> @cttz_zext_zero_def_vec(<2 x i32> %x) { 56; CHECK-LABEL: @cttz_zext_zero_def_vec( 57; CHECK-NEXT: [[Z:%.*]] = zext <2 x i32> [[X:%.*]] to <2 x i64> 58; CHECK-NEXT: [[TZ:%.*]] = tail call range(i64 0, 65) <2 x i64> @llvm.cttz.v2i64(<2 x i64> [[Z]], i1 false) 59; CHECK-NEXT: ret <2 x i64> [[TZ]] 60; 61 %z = zext <2 x i32> %x to <2 x i64> 62 %tz = tail call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %z, i1 false) 63 ret <2 x i64> %tz 64} 65 66define i32 @cttz_sext_zero_undef(i16 %x) { 67; CHECK-LABEL: @cttz_sext_zero_undef( 68; CHECK-NEXT: [[TMP1:%.*]] = call range(i16 0, 17) i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 true) 69; CHECK-NEXT: [[TZ:%.*]] = zext nneg i16 [[TMP1]] to i32 70; CHECK-NEXT: ret i32 [[TZ]] 71; 72 %s = sext i16 %x to i32 73 %tz = call i32 @llvm.cttz.i32(i32 %s, i1 true) 74 ret i32 %tz 75} 76 77define i32 @cttz_sext_zero_def(i16 %x) { 78; CHECK-LABEL: @cttz_sext_zero_def( 79; CHECK-NEXT: [[TMP1:%.*]] = zext i16 [[X:%.*]] to i32 80; CHECK-NEXT: [[TZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[TMP1]], i1 false) 81; CHECK-NEXT: ret i32 [[TZ]] 82; 83 %s = sext i16 %x to i32 84 %tz = call i32 @llvm.cttz.i32(i32 %s, i1 false) 85 ret i32 %tz 86} 87 88define i32 @cttz_sext_zero_undef_extra_use(i16 %x) { 89; CHECK-LABEL: @cttz_sext_zero_undef_extra_use( 90; CHECK-NEXT: [[S:%.*]] = sext i16 [[X:%.*]] to i32 91; CHECK-NEXT: call void @use(i32 [[S]]) 92; CHECK-NEXT: [[TZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[S]], i1 true) 93; CHECK-NEXT: ret i32 [[TZ]] 94; 95 %s = sext i16 %x to i32 96 call void @use(i32 %s) 97 %tz = call i32 @llvm.cttz.i32(i32 %s, i1 true) 98 ret i32 %tz 99} 100 101define <2 x i64> @cttz_sext_zero_undef_vec(<2 x i32> %x) { 102; CHECK-LABEL: @cttz_sext_zero_undef_vec( 103; CHECK-NEXT: [[TMP1:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[X:%.*]], i1 true) 104; CHECK-NEXT: [[TZ:%.*]] = zext nneg <2 x i32> [[TMP1]] to <2 x i64> 105; CHECK-NEXT: ret <2 x i64> [[TZ]] 106; 107 %s = sext <2 x i32> %x to <2 x i64> 108 %tz = tail call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %s, i1 true) 109 ret <2 x i64> %tz 110} 111 112define <2 x i64> @cttz_sext_zero_def_vec(<2 x i32> %x) { 113; CHECK-LABEL: @cttz_sext_zero_def_vec( 114; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i32> [[X:%.*]] to <2 x i64> 115; CHECK-NEXT: [[TZ:%.*]] = call range(i64 0, 65) <2 x i64> @llvm.cttz.v2i64(<2 x i64> [[TMP1]], i1 false) 116; CHECK-NEXT: ret <2 x i64> [[TZ]] 117; 118 %s = sext <2 x i32> %x to <2 x i64> 119 %tz = tail call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %s, i1 false) 120 ret <2 x i64> %tz 121} 122 123define i32 @cttz_of_lowest_set_bit(i32 %x) { 124; CHECK-LABEL: @cttz_of_lowest_set_bit( 125; CHECK-NEXT: [[TZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false) 126; CHECK-NEXT: ret i32 [[TZ]] 127; 128 %sub = sub i32 0, %x 129 %and = and i32 %sub, %x 130 %tz = call i32 @llvm.cttz.i32(i32 %and, i1 false) 131 ret i32 %tz 132} 133 134define i32 @cttz_of_lowest_set_bit_commuted(i32 %xx) { 135; CHECK-LABEL: @cttz_of_lowest_set_bit_commuted( 136; CHECK-NEXT: [[X:%.*]] = udiv i32 42, [[XX:%.*]] 137; CHECK-NEXT: [[TZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X]], i1 false) 138; CHECK-NEXT: ret i32 [[TZ]] 139; 140 %x = udiv i32 42, %xx ; thwart complexity-based canonicalization 141 %sub = sub i32 0, %x 142 %and = and i32 %x, %sub 143 %tz = call i32 @llvm.cttz.i32(i32 %and, i1 false) 144 ret i32 %tz 145} 146 147define i32 @cttz_of_lowest_set_bit_poison_flag(i32 %x) { 148; CHECK-LABEL: @cttz_of_lowest_set_bit_poison_flag( 149; CHECK-NEXT: [[TZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 true) 150; CHECK-NEXT: ret i32 [[TZ]] 151; 152 %sub = sub i32 0, %x 153 %and = and i32 %sub, %x 154 %tz = call i32 @llvm.cttz.i32(i32 %and, i1 true) 155 ret i32 %tz 156} 157 158define <2 x i64> @cttz_of_lowest_set_bit_vec(<2 x i64> %x) { 159; CHECK-LABEL: @cttz_of_lowest_set_bit_vec( 160; CHECK-NEXT: [[TZ:%.*]] = call range(i64 0, 65) <2 x i64> @llvm.cttz.v2i64(<2 x i64> [[X:%.*]], i1 false) 161; CHECK-NEXT: ret <2 x i64> [[TZ]] 162; 163 %sub = sub <2 x i64> zeroinitializer, %x 164 %and = and <2 x i64> %sub, %x 165 %tz = call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %and, i1 false) 166 ret <2 x i64> %tz 167} 168 169define <2 x i64> @cttz_of_lowest_set_bit_vec_undef(<2 x i64> %x) { 170; CHECK-LABEL: @cttz_of_lowest_set_bit_vec_undef( 171; CHECK-NEXT: [[TZ:%.*]] = call range(i64 0, 65) <2 x i64> @llvm.cttz.v2i64(<2 x i64> [[X:%.*]], i1 false) 172; CHECK-NEXT: ret <2 x i64> [[TZ]] 173; 174 %sub = sub <2 x i64> zeroinitializer, %x 175 %and = and <2 x i64> %sub, %x 176 %tz = call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %and, i1 false) 177 ret <2 x i64> %tz 178} 179 180define i32 @cttz_of_lowest_set_bit_wrong_const(i32 %x) { 181; CHECK-LABEL: @cttz_of_lowest_set_bit_wrong_const( 182; CHECK-NEXT: [[SUB:%.*]] = sub i32 1, [[X:%.*]] 183; CHECK-NEXT: [[AND:%.*]] = and i32 [[SUB]], [[X]] 184; CHECK-NEXT: [[TZ:%.*]] = call range(i32 1, 33) i32 @llvm.cttz.i32(i32 [[AND]], i1 false) 185; CHECK-NEXT: ret i32 [[TZ]] 186; 187 %sub = sub i32 1, %x 188 %and = and i32 %sub, %x 189 %tz = call i32 @llvm.cttz.i32(i32 %and, i1 false) 190 ret i32 %tz 191} 192 193define i32 @cttz_of_lowest_set_bit_wrong_operand(i32 %x, i32 %y) { 194; CHECK-LABEL: @cttz_of_lowest_set_bit_wrong_operand( 195; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[Y:%.*]] 196; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[SUB]] 197; CHECK-NEXT: [[TZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[AND]], i1 false) 198; CHECK-NEXT: ret i32 [[TZ]] 199; 200 %sub = sub i32 0, %y 201 %and = and i32 %sub, %x 202 %tz = call i32 @llvm.cttz.i32(i32 %and, i1 false) 203 ret i32 %tz 204} 205 206define i32 @cttz_of_lowest_set_bit_wrong_intrinsic(i32 %x) { 207; CHECK-LABEL: @cttz_of_lowest_set_bit_wrong_intrinsic( 208; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[X:%.*]] 209; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[SUB]] 210; CHECK-NEXT: [[TZ:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[AND]], i1 false) 211; CHECK-NEXT: ret i32 [[TZ]] 212; 213 %sub = sub i32 0, %x 214 %and = and i32 %sub, %x 215 %tz = call i32 @llvm.ctlz.i32(i32 %and, i1 false) 216 ret i32 %tz 217} 218 219define i32 @cttz_of_power_of_two(i32 %x) { 220; CHECK-LABEL: @cttz_of_power_of_two( 221; CHECK-NEXT: [[R:%.*]] = sub i32 32, [[X:%.*]] 222; CHECK-NEXT: ret i32 [[R]] 223; 224 %lshr = lshr i32 -1, %x 225 %add = add i32 %lshr, 1 226 %r = call i32 @llvm.cttz.i32(i32 %add, i1 false) 227 ret i32 %r 228} 229 230define i32 @cttz_of_power_of_two_zero_poison(i32 %x) { 231; CHECK-LABEL: @cttz_of_power_of_two_zero_poison( 232; CHECK-NEXT: [[R:%.*]] = sub i32 32, [[X:%.*]] 233; CHECK-NEXT: ret i32 [[R]] 234; 235 %lshr = lshr i32 -1, %x 236 %add = add i32 %lshr, 1 237 %r = call i32 @llvm.cttz.i32(i32 %add, i1 true) 238 ret i32 %r 239} 240 241define i32 @cttz_of_power_of_two_wrong_intrinsic(i32 %x) { 242; CHECK-LABEL: @cttz_of_power_of_two_wrong_intrinsic( 243; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 -1, [[X:%.*]] 244; CHECK-NEXT: [[ADD:%.*]] = add i32 [[LSHR]], 1 245; CHECK-NEXT: [[R:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[ADD]], i1 false) 246; CHECK-NEXT: ret i32 [[R]] 247; 248 %lshr = lshr i32 -1, %x 249 %add = add i32 %lshr, 1 250 %r = call i32 @llvm.ctlz.i32(i32 %add, i1 false) 251 ret i32 %r 252} 253 254define i32 @cttz_of_power_of_two_wrong_constant_1(i32 %x) { 255; CHECK-LABEL: @cttz_of_power_of_two_wrong_constant_1( 256; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 -2, [[X:%.*]] 257; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[LSHR]], 1 258; CHECK-NEXT: [[R:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[ADD]], i1 true) 259; CHECK-NEXT: ret i32 [[R]] 260; 261 %lshr = lshr i32 -2, %x 262 %add = add i32 %lshr, 1 263 %r = call i32 @llvm.cttz.i32(i32 %add, i1 false) 264 ret i32 %r 265} 266 267define i32 @cttz_of_power_of_two_wrong_constant_2(i32 %x) { 268; CHECK-LABEL: @cttz_of_power_of_two_wrong_constant_2( 269; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 -1, [[X:%.*]] 270; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[LSHR]], -1 271; CHECK-NEXT: [[R:%.*]] = call range(i32 1, 33) i32 @llvm.cttz.i32(i32 [[ADD]], i1 false) 272; CHECK-NEXT: ret i32 [[R]] 273; 274 %lshr = lshr i32 -1, %x 275 %add = add i32 %lshr, -1 276 %r = call i32 @llvm.cttz.i32(i32 %add, i1 false) 277 ret i32 %r 278} 279 280define i16 @cttz_assume(i16 %x) { 281; CHECK-LABEL: @cttz_assume( 282; CHECK-NEXT: [[ADD:%.*]] = add i16 [[X:%.*]], 1 283; CHECK-NEXT: [[COND0:%.*]] = icmp ult i16 [[ADD]], 10 284; CHECK-NEXT: call void @llvm.assume(i1 [[COND0]]) 285; CHECK-NEXT: [[COND1:%.*]] = icmp ne i16 [[X]], 0 286; CHECK-NEXT: call void @llvm.assume(i1 [[COND1]]) 287; CHECK-NEXT: [[CTTZ:%.*]] = call range(i16 0, 17) i16 @llvm.cttz.i16(i16 [[X]], i1 true) 288; CHECK-NEXT: ret i16 [[CTTZ]] 289; 290 %add = add i16 %x, 1 291 %cond0 = icmp ult i16 %add, 10 292 call void @llvm.assume(i1 %cond0) 293 294 %cond1 = icmp ne i16 %x, 0 295 call void @llvm.assume(i1 %cond1) 296 297 %cttz = call i16 @llvm.cttz.i16(i16 %x, i1 false) 298 ret i16 %cttz 299} 300 301 302declare void @use.i8(i8) 303define i8 @fold_ctz_log2(i8 %x) { 304; CHECK-LABEL: @fold_ctz_log2( 305; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 5) 306; CHECK-NEXT: ret i8 [[R]] 307; 308 %p2 = shl i8 1, %x 309 %v = call i8 @llvm.umin(i8 %p2, i8 32) 310 %r = call i8 @llvm.cttz(i8 %v, i1 false) 311 ret i8 %r 312} 313 314define i9 @fold_ctz_log2_i9_okay(i9 %x) { 315; CHECK-LABEL: @fold_ctz_log2_i9_okay( 316; CHECK-NEXT: [[R:%.*]] = call i9 @llvm.umin.i9(i9 [[X:%.*]], i9 5) 317; CHECK-NEXT: ret i9 [[R]] 318; 319 %p2 = shl i9 1, %x 320 %v = call i9 @llvm.umin(i9 %p2, i9 32) 321 %r = call i9 @llvm.cttz(i9 %v, i1 false) 322 ret i9 %r 323} 324 325define i8 @fold_ctz_log2_maybe_z(i8 %x, i8 %y, i1 %c) { 326; CHECK-LABEL: @fold_ctz_log2_maybe_z( 327; CHECK-NEXT: [[V:%.*]] = shl i8 2, [[V_V:%.*]] 328; CHECK-NEXT: [[P2_2:%.*]] = shl i8 4, [[Y:%.*]] 329; CHECK-NEXT: [[V1:%.*]] = select i1 [[C:%.*]], i8 [[V]], i8 [[P2_2]] 330; CHECK-NEXT: [[R:%.*]] = call range(i8 1, 9) i8 @llvm.cttz.i8(i8 [[V1]], i1 false) 331; CHECK-NEXT: ret i8 [[R]] 332; 333 %p2 = shl i8 2, %x 334 %p2_2 = shl i8 4, %y 335 %v = select i1 %c, i8 %p2, i8 %p2_2 336 %r = call i8 @llvm.cttz(i8 %v, i1 false) 337 ret i8 %r 338} 339 340define i8 @fold_ctz_log2_maybe_z_okay(i8 %x, i8 %y, i1 %c) { 341; CHECK-LABEL: @fold_ctz_log2_maybe_z_okay( 342; CHECK-NEXT: [[X:%.*]] = add i8 [[X1:%.*]], 1 343; CHECK-NEXT: [[Y:%.*]] = add i8 [[Y1:%.*]], 2 344; CHECK-NEXT: [[V_V:%.*]] = select i1 [[C:%.*]], i8 [[X]], i8 [[Y]] 345; CHECK-NEXT: ret i8 [[V_V]] 346; 347 %p2 = shl i8 2, %x 348 %p2_2 = shl i8 4, %y 349 %v = select i1 %c, i8 %p2, i8 %p2_2 350 %r = call i8 @llvm.cttz(i8 %v, i1 true) 351 ret i8 %r 352} 353 354define i8 @fold_clz_log2(i8 %x) { 355; CHECK-LABEL: @fold_clz_log2( 356; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 5) 357; CHECK-NEXT: [[R:%.*]] = xor i8 [[TMP1]], 7 358; CHECK-NEXT: ret i8 [[R]] 359; 360 %p2 = shl i8 1, %x 361 %v = call i8 @llvm.umin(i8 %p2, i8 32) 362 %r = call i8 @llvm.ctlz(i8 %v, i1 false) 363 ret i8 %r 364} 365 366define i8 @fold_clz_log2_multiuse_fail(i8 %x) { 367; CHECK-LABEL: @fold_clz_log2_multiuse_fail( 368; CHECK-NEXT: [[P2:%.*]] = shl nuw i8 2, [[X:%.*]] 369; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.umin.i8(i8 [[P2]], i8 32) 370; CHECK-NEXT: call void @use.i8(i8 [[V]]) 371; CHECK-NEXT: [[R:%.*]] = call range(i8 2, 9) i8 @llvm.ctlz.i8(i8 [[V]], i1 true) 372; CHECK-NEXT: ret i8 [[R]] 373; 374 %p2 = shl nuw i8 2, %x 375 %v = call i8 @llvm.umin(i8 %p2, i8 32) 376 call void @use.i8(i8 %v) 377 %r = call i8 @llvm.ctlz(i8 %v, i1 true) 378 ret i8 %r 379} 380 381 382define i9 @fold_clz_log2_i9(i9 %x) { 383; CHECK-LABEL: @fold_clz_log2_i9( 384; CHECK-NEXT: [[TMP1:%.*]] = call i9 @llvm.umin.i9(i9 [[X:%.*]], i9 5) 385; CHECK-NEXT: [[R:%.*]] = sub nuw nsw i9 8, [[TMP1]] 386; CHECK-NEXT: ret i9 [[R]] 387; 388 %p2 = shl i9 1, %x 389 %v = call i9 @llvm.umin(i9 %p2, i9 32) 390 %r = call i9 @llvm.ctlz(i9 %v, i1 true) 391 ret i9 %r 392} 393