731 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=instcombine -S < %s | FileCheck %s3 4; This test is to verify that the instruction combiner is able to fold5; a cttz/ctlz followed by a icmp + select into a single cttz/ctlz with6; the 'is_zero_undef' flag cleared.7 8define i16 @test1(i16 %x) {9; CHECK-LABEL: @test1(10; CHECK-NEXT: [[CT:%.*]] = tail call range(i16 0, 17) i16 @llvm.ctlz.i16(i16 [[X:%.*]], i1 false)11; CHECK-NEXT: ret i16 [[CT]]12;13 %ct = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true)14 %tobool = icmp ne i16 %x, 015 %cond = select i1 %tobool, i16 %ct, i16 1616 ret i16 %cond17}18 19define i32 @test2(i32 %x) {20; CHECK-LABEL: @test2(21; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false)22; CHECK-NEXT: ret i32 [[CT]]23;24 %ct = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)25 %tobool = icmp ne i32 %x, 026 %cond = select i1 %tobool, i32 %ct, i32 3227 ret i32 %cond28}29 30define i64 @test3(i64 %x) {31; CHECK-LABEL: @test3(32; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.ctlz.i64(i64 [[X:%.*]], i1 false)33; CHECK-NEXT: ret i64 [[CT]]34;35 %ct = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)36 %tobool = icmp ne i64 %x, 037 %cond = select i1 %tobool, i64 %ct, i64 6438 ret i64 %cond39}40 41define i16 @test4(i16 %x) {42; CHECK-LABEL: @test4(43; CHECK-NEXT: [[CT:%.*]] = tail call range(i16 0, 17) i16 @llvm.ctlz.i16(i16 [[X:%.*]], i1 false)44; CHECK-NEXT: ret i16 [[CT]]45;46 %ct = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true)47 %tobool = icmp eq i16 %x, 048 %cond = select i1 %tobool, i16 16, i16 %ct49 ret i16 %cond50}51 52define i16 @test4_with_range(i16 %x) {53; CHECK-LABEL: @test4_with_range(54; CHECK-NEXT: [[CT:%.*]] = call range(i16 0, 17) i16 @llvm.ctlz.i16(i16 [[X:%.*]], i1 false)55; CHECK-NEXT: ret i16 [[CT]]56;57 %ct = call range(i16 0, 16) i16 @llvm.ctlz.i16(i16 %x, i1 true)58 %tobool = icmp eq i16 %x, 059 %cond = select i1 %tobool, i16 16, i16 %ct60 ret i16 %cond61}62 63define i32 @test5(i32 %x) {64; CHECK-LABEL: @test5(65; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false)66; CHECK-NEXT: ret i32 [[CT]]67;68 %ct = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)69 %tobool = icmp eq i32 %x, 070 %cond = select i1 %tobool, i32 32, i32 %ct71 ret i32 %cond72}73 74define i64 @test6(i64 %x) {75; CHECK-LABEL: @test6(76; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.ctlz.i64(i64 [[X:%.*]], i1 false)77; CHECK-NEXT: ret i64 [[CT]]78;79 %ct = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)80 %tobool = icmp eq i64 %x, 081 %cond = select i1 %tobool, i64 64, i64 %ct82 ret i64 %cond83}84 85define i16 @test1b(i16 %x) {86; CHECK-LABEL: @test1b(87; CHECK-NEXT: [[CT:%.*]] = tail call range(i16 0, 17) i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 false)88; CHECK-NEXT: ret i16 [[CT]]89;90 %ct = tail call i16 @llvm.cttz.i16(i16 %x, i1 true)91 %tobool = icmp ne i16 %x, 092 %cond = select i1 %tobool, i16 %ct, i16 1693 ret i16 %cond94}95 96define i32 @test2b(i32 %x) {97; CHECK-LABEL: @test2b(98; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)99; CHECK-NEXT: ret i32 [[CT]]100;101 %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)102 %tobool = icmp ne i32 %x, 0103 %cond = select i1 %tobool, i32 %ct, i32 32104 ret i32 %cond105}106 107define i64 @test3b(i64 %x) {108; CHECK-LABEL: @test3b(109; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 false)110; CHECK-NEXT: ret i64 [[CT]]111;112 %ct = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)113 %tobool = icmp ne i64 %x, 0114 %cond = select i1 %tobool, i64 %ct, i64 64115 ret i64 %cond116}117 118define i16 @test4b(i16 %x) {119; CHECK-LABEL: @test4b(120; CHECK-NEXT: [[CT:%.*]] = tail call range(i16 0, 17) i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 false)121; CHECK-NEXT: ret i16 [[CT]]122;123 %ct = tail call i16 @llvm.cttz.i16(i16 %x, i1 true)124 %tobool = icmp eq i16 %x, 0125 %cond = select i1 %tobool, i16 16, i16 %ct126 ret i16 %cond127}128 129define i16 @test4b_with_range(i16 %x) {130; CHECK-LABEL: @test4b_with_range(131; CHECK-NEXT: [[CT:%.*]] = call range(i16 0, 17) i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 false)132; CHECK-NEXT: ret i16 [[CT]]133;134 %ct = call range(i16 0, 16) i16 @llvm.cttz.i16(i16 %x, i1 true)135 %tobool = icmp eq i16 %x, 0136 %cond = select i1 %tobool, i16 16, i16 %ct137 ret i16 %cond138}139 140define i32 @test5b(i32 %x) {141; CHECK-LABEL: @test5b(142; CHECK-NEXT: entry:143; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)144; CHECK-NEXT: ret i32 [[CT]]145;146entry:147 %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)148 %tobool = icmp eq i32 %x, 0149 %cond = select i1 %tobool, i32 32, i32 %ct150 ret i32 %cond151}152 153define i64 @test6b(i64 %x) {154; CHECK-LABEL: @test6b(155; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 false)156; CHECK-NEXT: ret i64 [[CT]]157;158 %ct = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)159 %tobool = icmp eq i64 %x, 0160 %cond = select i1 %tobool, i64 64, i64 %ct161 ret i64 %cond162}163 164define i32 @test1c(i16 %x) {165; CHECK-LABEL: @test1c(166; CHECK-NEXT: [[CT:%.*]] = tail call range(i16 0, 17) i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 false)167; CHECK-NEXT: [[CAST2:%.*]] = zext nneg i16 [[CT]] to i32168; CHECK-NEXT: ret i32 [[CAST2]]169;170 %ct = tail call i16 @llvm.cttz.i16(i16 %x, i1 true)171 %cast2 = zext i16 %ct to i32172 %tobool = icmp ne i16 %x, 0173 %cond = select i1 %tobool, i32 %cast2, i32 16174 ret i32 %cond175}176 177define i64 @test2c(i16 %x) {178; CHECK-LABEL: @test2c(179; CHECK-NEXT: [[CT:%.*]] = tail call range(i16 0, 17) i16 @llvm.cttz.i16(i16 [[X:%.*]], i1 false)180; CHECK-NEXT: [[CONV:%.*]] = zext nneg i16 [[CT]] to i64181; CHECK-NEXT: ret i64 [[CONV]]182;183 %ct = tail call i16 @llvm.cttz.i16(i16 %x, i1 true)184 %conv = zext i16 %ct to i64185 %tobool = icmp ne i16 %x, 0186 %cond = select i1 %tobool, i64 %conv, i64 16187 ret i64 %cond188}189 190define i64 @test3c(i32 %x) {191; CHECK-LABEL: @test3c(192; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)193; CHECK-NEXT: [[CONV:%.*]] = zext nneg i32 [[CT]] to i64194; CHECK-NEXT: ret i64 [[CONV]]195;196 %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)197 %conv = zext i32 %ct to i64198 %tobool = icmp ne i32 %x, 0199 %cond = select i1 %tobool, i64 %conv, i64 32200 ret i64 %cond201}202 203define i32 @test4c(i16 %x) {204; CHECK-LABEL: @test4c(205; CHECK-NEXT: [[CT:%.*]] = tail call range(i16 0, 17) i16 @llvm.ctlz.i16(i16 [[X:%.*]], i1 false)206; CHECK-NEXT: [[CAST:%.*]] = zext nneg i16 [[CT]] to i32207; CHECK-NEXT: ret i32 [[CAST]]208;209 %ct = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true)210 %cast = zext i16 %ct to i32211 %tobool = icmp ne i16 %x, 0212 %cond = select i1 %tobool, i32 %cast, i32 16213 ret i32 %cond214}215 216define i64 @test5c(i16 %x) {217; CHECK-LABEL: @test5c(218; CHECK-NEXT: [[CT:%.*]] = tail call range(i16 0, 17) i16 @llvm.ctlz.i16(i16 [[X:%.*]], i1 false)219; CHECK-NEXT: [[CAST:%.*]] = zext nneg i16 [[CT]] to i64220; CHECK-NEXT: ret i64 [[CAST]]221;222 %ct = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true)223 %cast = zext i16 %ct to i64224 %tobool = icmp ne i16 %x, 0225 %cond = select i1 %tobool, i64 %cast, i64 16226 ret i64 %cond227}228 229define i64 @test6c(i32 %x) {230; CHECK-LABEL: @test6c(231; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false)232; CHECK-NEXT: [[CAST:%.*]] = zext nneg i32 [[CT]] to i64233; CHECK-NEXT: ret i64 [[CAST]]234;235 %ct = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)236 %cast = zext i32 %ct to i64237 %tobool = icmp ne i32 %x, 0238 %cond = select i1 %tobool, i64 %cast, i64 32239 ret i64 %cond240}241 242define i16 @test1d(i64 %x) {243; CHECK-LABEL: @test1d(244; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 false)245; CHECK-NEXT: [[CONV:%.*]] = trunc nuw nsw i64 [[CT]] to i16246; CHECK-NEXT: ret i16 [[CONV]]247;248 %ct = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)249 %conv = trunc i64 %ct to i16250 %tobool = icmp ne i64 %x, 0251 %cond = select i1 %tobool, i16 %conv, i16 64252 ret i16 %cond253}254 255define i32 @test2d(i64 %x) {256; CHECK-LABEL: @test2d(257; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 false)258; CHECK-NEXT: [[CAST:%.*]] = trunc nuw nsw i64 [[CT]] to i32259; CHECK-NEXT: ret i32 [[CAST]]260;261 %ct = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)262 %cast = trunc i64 %ct to i32263 %tobool = icmp ne i64 %x, 0264 %cond = select i1 %tobool, i32 %cast, i32 64265 ret i32 %cond266}267 268define i16 @test3d(i32 %x) {269; CHECK-LABEL: @test3d(270; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)271; CHECK-NEXT: [[CAST:%.*]] = trunc nuw nsw i32 [[CT]] to i16272; CHECK-NEXT: ret i16 [[CAST]]273;274 %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)275 %cast = trunc i32 %ct to i16276 %tobool = icmp ne i32 %x, 0277 %cond = select i1 %tobool, i16 %cast, i16 32278 ret i16 %cond279}280 281define i16 @test4d(i64 %x) {282; CHECK-LABEL: @test4d(283; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.ctlz.i64(i64 [[X:%.*]], i1 false)284; CHECK-NEXT: [[CAST:%.*]] = trunc nuw nsw i64 [[CT]] to i16285; CHECK-NEXT: ret i16 [[CAST]]286;287 %ct = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)288 %cast = trunc i64 %ct to i16289 %tobool = icmp ne i64 %x, 0290 %cond = select i1 %tobool, i16 %cast, i16 64291 ret i16 %cond292}293 294define i32 @test5d(i64 %x) {295; CHECK-LABEL: @test5d(296; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.ctlz.i64(i64 [[X:%.*]], i1 false)297; CHECK-NEXT: [[CAST:%.*]] = trunc nuw nsw i64 [[CT]] to i32298; CHECK-NEXT: ret i32 [[CAST]]299;300 %ct = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)301 %cast = trunc i64 %ct to i32302 %tobool = icmp ne i64 %x, 0303 %cond = select i1 %tobool, i32 %cast, i32 64304 ret i32 %cond305}306 307; Same as above, but the counting zeros on an inverted operand with opposite compare.308 309define i32 @not_op_ctlz(i64 %x) {310; CHECK-LABEL: @not_op_ctlz(311; CHECK-NEXT: [[N:%.*]] = xor i64 [[X:%.*]], -1312; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.ctlz.i64(i64 [[N]], i1 false)313; CHECK-NEXT: [[CAST:%.*]] = trunc nuw nsw i64 [[CT]] to i32314; CHECK-NEXT: ret i32 [[CAST]]315;316 %n = xor i64 %x, -1317 %ct = tail call i64 @llvm.ctlz.i64(i64 %n, i1 true)318 %cast = trunc i64 %ct to i32319 %tobool = icmp eq i64 %x, -1320 %r = select i1 %tobool, i32 64, i32 %cast321 ret i32 %r322}323 324define i32 @not_op_cttz(i64 %x) {325; CHECK-LABEL: @not_op_cttz(326; CHECK-NEXT: [[N:%.*]] = xor i64 [[X:%.*]], -1327; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.cttz.i64(i64 [[N]], i1 false)328; CHECK-NEXT: [[CAST:%.*]] = trunc nuw nsw i64 [[CT]] to i32329; CHECK-NEXT: ret i32 [[CAST]]330;331 %n = xor i64 %x, -1332 %ct = tail call i64 @llvm.cttz.i64(i64 %n, i1 true)333 %cast = trunc i64 %ct to i32334 %tobool = icmp eq i64 %x, -1335 %r = select i1 %tobool, i32 64, i32 %cast336 ret i32 %r337}338 339; negative test340 341define i32 @not_op_ctlz_wrong_xor_op1(i64 %x) {342; CHECK-LABEL: @not_op_ctlz_wrong_xor_op1(343; CHECK-NEXT: [[N:%.*]] = xor i64 [[X:%.*]], -2344; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.ctlz.i64(i64 [[N]], i1 true)345; CHECK-NEXT: [[CAST:%.*]] = trunc nuw nsw i64 [[CT]] to i32346; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X]], -1347; CHECK-NEXT: [[R:%.*]] = select i1 [[TOBOOL]], i32 64, i32 [[CAST]]348; CHECK-NEXT: ret i32 [[R]]349;350 %n = xor i64 %x, -2351 %ct = tail call i64 @llvm.ctlz.i64(i64 %n, i1 true)352 %cast = trunc i64 %ct to i32353 %tobool = icmp eq i64 %x, -1354 %r = select i1 %tobool, i32 64, i32 %cast355 ret i32 %r356}357 358; negative test359 360define i32 @not_op_ctlz_wrong_xor_op0(i64 %x, i64 %y) {361; CHECK-LABEL: @not_op_ctlz_wrong_xor_op0(362; CHECK-NEXT: [[N:%.*]] = xor i64 [[Y:%.*]], -1363; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.ctlz.i64(i64 [[N]], i1 true)364; CHECK-NEXT: [[CAST:%.*]] = trunc nuw nsw i64 [[CT]] to i32365; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], -1366; CHECK-NEXT: [[R:%.*]] = select i1 [[TOBOOL]], i32 64, i32 [[CAST]]367; CHECK-NEXT: ret i32 [[R]]368;369 %n = xor i64 %y, -1370 %ct = tail call i64 @llvm.ctlz.i64(i64 %n, i1 true)371 %cast = trunc i64 %ct to i32372 %tobool = icmp eq i64 %x, -1373 %r = select i1 %tobool, i32 64, i32 %cast374 ret i32 %r375}376 377; negative test378 379define i32 @not_op_cttz_wrong_cmp(i64 %x) {380; CHECK-LABEL: @not_op_cttz_wrong_cmp(381; CHECK-NEXT: [[N:%.*]] = xor i64 [[X:%.*]], -1382; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.cttz.i64(i64 [[N]], i1 true)383; CHECK-NEXT: [[CAST:%.*]] = trunc nuw nsw i64 [[CT]] to i32384; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X]], 0385; CHECK-NEXT: [[R:%.*]] = select i1 [[TOBOOL]], i32 64, i32 [[CAST]]386; CHECK-NEXT: ret i32 [[R]]387;388 %n = xor i64 %x, -1389 %ct = tail call i64 @llvm.cttz.i64(i64 %n, i1 true)390 %cast = trunc i64 %ct to i32391 %tobool = icmp eq i64 %x, 0392 %r = select i1 %tobool, i32 64, i32 %cast393 ret i32 %r394}395 396define i16 @test6d(i32 %x) {397; CHECK-LABEL: @test6d(398; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false)399; CHECK-NEXT: [[CAST:%.*]] = trunc nuw nsw i32 [[CT]] to i16400; CHECK-NEXT: ret i16 [[CAST]]401;402 %ct = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)403 %cast = trunc i32 %ct to i16404 %tobool = icmp ne i32 %x, 0405 %cond = select i1 %tobool, i16 %cast, i16 32406 ret i16 %cond407}408 409define i64 @select_bug1(i32 %x) {410; CHECK-LABEL: @select_bug1(411; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)412; CHECK-NEXT: [[CONV:%.*]] = zext nneg i32 [[CT]] to i64413; CHECK-NEXT: ret i64 [[CONV]]414;415 %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)416 %conv = zext i32 %ct to i64417 %tobool = icmp ne i32 %x, 0418 %cond = select i1 %tobool, i64 %conv, i64 32419 ret i64 %cond420}421 422define i16 @select_bug2(i32 %x) {423; CHECK-LABEL: @select_bug2(424; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)425; CHECK-NEXT: [[CONV:%.*]] = trunc nuw nsw i32 [[CT]] to i16426; CHECK-NEXT: ret i16 [[CONV]]427;428 %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)429 %conv = trunc i32 %ct to i16430 %tobool = icmp ne i32 %x, 0431 %cond = select i1 %tobool, i16 %conv, i16 32432 ret i16 %cond433}434 435define i128 @test7(i128 %x) {436; CHECK-LABEL: @test7(437; CHECK-NEXT: [[CT:%.*]] = tail call range(i128 0, 129) i128 @llvm.ctlz.i128(i128 [[X:%.*]], i1 false)438; CHECK-NEXT: ret i128 [[CT]]439;440 %ct = tail call i128 @llvm.ctlz.i128(i128 %x, i1 true)441 %tobool = icmp ne i128 %x, 0442 %cond = select i1 %tobool, i128 %ct, i128 128443 ret i128 %cond444}445 446define i128 @test8(i128 %x) {447; CHECK-LABEL: @test8(448; CHECK-NEXT: [[CT:%.*]] = tail call range(i128 0, 129) i128 @llvm.cttz.i128(i128 [[X:%.*]], i1 false)449; CHECK-NEXT: ret i128 [[CT]]450;451 %ct = tail call i128 @llvm.cttz.i128(i128 %x, i1 true)452 %tobool = icmp ne i128 %x, 0453 %cond = select i1 %tobool, i128 %ct, i128 128454 ret i128 %cond455}456 457define i32 @test_ctlz_not_bw(i32 %x) {458; CHECK-LABEL: @test_ctlz_not_bw(459; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 true)460; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[X]], 0461; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP_NOT]], i32 123, i32 [[CT]]462; CHECK-NEXT: ret i32 [[RES]]463;464 %ct = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)465 %cmp = icmp ne i32 %x, 0466 %res = select i1 %cmp, i32 %ct, i32 123467 ret i32 %res468}469 470define i32 @test_ctlz_not_bw_multiuse(i32 %x) {471; CHECK-LABEL: @test_ctlz_not_bw_multiuse(472; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false)473; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[X]], 0474; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP_NOT]], i32 123, i32 [[CT]]475; CHECK-NEXT: [[RES:%.*]] = or i32 [[SEL]], [[CT]]476; CHECK-NEXT: ret i32 [[RES]]477;478 %ct = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)479 %cmp = icmp ne i32 %x, 0480 %sel = select i1 %cmp, i32 %ct, i32 123481 %res = or i32 %sel, %ct482 ret i32 %res483}484 485define i32 @test_cttz_not_bw(i32 %x) {486; CHECK-LABEL: @test_cttz_not_bw(487; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 true)488; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[X]], 0489; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP_NOT]], i32 123, i32 [[CT]]490; CHECK-NEXT: ret i32 [[RES]]491;492 %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)493 %cmp = icmp ne i32 %x, 0494 %res = select i1 %cmp, i32 %ct, i32 123495 ret i32 %res496}497 498define i32 @test_cttz_not_bw_noundef(i32 %x) {499; CHECK-LABEL: @test_cttz_not_bw_noundef(500; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 true)501; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[X]], 0502; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP_NOT]], i32 123, i32 [[CT]]503; CHECK-NEXT: ret i32 [[RES]]504;505 %ct = tail call noundef i32 @llvm.cttz.i32(i32 %x, i1 false)506 %cmp = icmp ne i32 %x, 0507 %res = select i1 %cmp, i32 %ct, i32 123508 ret i32 %res509}510 511define i32 @test_cttz_not_bw_multiuse(i32 %x) {512; CHECK-LABEL: @test_cttz_not_bw_multiuse(513; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)514; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[X]], 0515; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP_NOT]], i32 123, i32 [[CT]]516; CHECK-NEXT: [[RES:%.*]] = or i32 [[SEL]], [[CT]]517; CHECK-NEXT: ret i32 [[RES]]518;519 %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)520 %cmp = icmp ne i32 %x, 0521 %sel = select i1 %cmp, i32 %ct, i32 123522 %res = or i32 %sel, %ct523 ret i32 %res524}525 526define <2 x i32> @test_ctlz_bw_vec(<2 x i32> %x) {527; CHECK-LABEL: @test_ctlz_bw_vec(528; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) <2 x i32> @llvm.ctlz.v2i32(<2 x i32> [[X:%.*]], i1 false)529; CHECK-NEXT: ret <2 x i32> [[CT]]530;531 %ct = tail call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %x, i1 true)532 %cmp = icmp ne <2 x i32> %x, zeroinitializer533 %res = select <2 x i1> %cmp, <2 x i32> %ct, <2 x i32> <i32 32, i32 32>534 ret <2 x i32> %res535}536 537define <2 x i32> @test_ctlz_not_bw_vec(<2 x i32> %x) {538; CHECK-LABEL: @test_ctlz_not_bw_vec(539; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) <2 x i32> @llvm.ctlz.v2i32(<2 x i32> [[X:%.*]], i1 true)540; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq <2 x i32> [[X]], zeroinitializer541; CHECK-NEXT: [[RES:%.*]] = select <2 x i1> [[CMP_NOT]], <2 x i32> zeroinitializer, <2 x i32> [[CT]]542; CHECK-NEXT: ret <2 x i32> [[RES]]543;544 %ct = tail call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %x, i1 false)545 %cmp = icmp ne <2 x i32> %x, zeroinitializer546 %res = select <2 x i1> %cmp, <2 x i32> %ct, <2 x i32> <i32 0, i32 0>547 ret <2 x i32> %res548}549 550define <2 x i32> @test_cttz_bw_vec(<2 x i32> %x) {551; CHECK-LABEL: @test_cttz_bw_vec(552; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[X:%.*]], i1 false)553; CHECK-NEXT: ret <2 x i32> [[CT]]554;555 %ct = tail call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %x, i1 true)556 %cmp = icmp ne <2 x i32> %x, zeroinitializer557 %res = select <2 x i1> %cmp, <2 x i32> %ct, <2 x i32> <i32 32, i32 32>558 ret <2 x i32> %res559}560 561define <2 x i32> @test_cttz_not_bw_vec(<2 x i32> %x) {562; CHECK-LABEL: @test_cttz_not_bw_vec(563; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[X:%.*]], i1 true)564; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq <2 x i32> [[X]], zeroinitializer565; CHECK-NEXT: [[RES:%.*]] = select <2 x i1> [[CMP_NOT]], <2 x i32> zeroinitializer, <2 x i32> [[CT]]566; CHECK-NEXT: ret <2 x i32> [[RES]]567;568 %ct = tail call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %x, i1 false)569 %cmp = icmp ne <2 x i32> %x, zeroinitializer570 %res = select <2 x i1> %cmp, <2 x i32> %ct, <2 x i32> <i32 0, i32 0>571 ret <2 x i32> %res572}573 574define i32 @test_multiuse_def(i32 %x, ptr %p) {575; CHECK-LABEL: @test_multiuse_def(576; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false)577; CHECK-NEXT: store i32 [[CT]], ptr [[P:%.*]], align 4578; CHECK-NEXT: ret i32 [[CT]]579;580 %ct = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)581 %tobool = icmp ne i32 %x, 0582 %cond = select i1 %tobool, i32 %ct, i32 32583 store i32 %ct, ptr %p584 ret i32 %cond585}586 587define i32 @test_multiuse_undef(i32 %x, ptr %p) {588; CHECK-LABEL: @test_multiuse_undef(589; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false)590; CHECK-NEXT: store i32 [[CT]], ptr [[P:%.*]], align 4591; CHECK-NEXT: ret i32 [[CT]]592;593 %ct = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)594 %tobool = icmp ne i32 %x, 0595 %cond = select i1 %tobool, i32 %ct, i32 32596 store i32 %ct, ptr %p597 ret i32 %cond598}599 600define i64 @test_multiuse_zext_def(i32 %x, ptr %p) {601; CHECK-LABEL: @test_multiuse_zext_def(602; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)603; CHECK-NEXT: [[CONV:%.*]] = zext nneg i32 [[CT]] to i64604; CHECK-NEXT: store i64 [[CONV]], ptr [[P:%.*]], align 4605; CHECK-NEXT: ret i64 [[CONV]]606;607 %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)608 %conv = zext i32 %ct to i64609 %tobool = icmp ne i32 %x, 0610 %cond = select i1 %tobool, i64 %conv, i64 32611 store i64 %conv, ptr %p612 ret i64 %cond613}614 615define i64 @test_multiuse_zext_undef(i32 %x, ptr %p) {616; CHECK-LABEL: @test_multiuse_zext_undef(617; CHECK-NEXT: [[CT:%.*]] = tail call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[X:%.*]], i1 false)618; CHECK-NEXT: [[CONV:%.*]] = zext nneg i32 [[CT]] to i64619; CHECK-NEXT: store i64 [[CONV]], ptr [[P:%.*]], align 4620; CHECK-NEXT: ret i64 [[CONV]]621;622 %ct = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)623 %conv = zext i32 %ct to i64624 %tobool = icmp ne i32 %x, 0625 %cond = select i1 %tobool, i64 %conv, i64 32626 store i64 %conv, ptr %p627 ret i64 %cond628}629 630define i16 @test_multiuse_trunc_def(i64 %x, ptr %p) {631; CHECK-LABEL: @test_multiuse_trunc_def(632; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 false)633; CHECK-NEXT: [[CONV:%.*]] = trunc nuw nsw i64 [[CT]] to i16634; CHECK-NEXT: store i16 [[CONV]], ptr [[P:%.*]], align 2635; CHECK-NEXT: ret i16 [[CONV]]636;637 %ct = tail call i64 @llvm.cttz.i64(i64 %x, i1 false)638 %conv = trunc i64 %ct to i16639 %tobool = icmp ne i64 %x, 0640 %cond = select i1 %tobool, i16 %conv, i16 64641 store i16 %conv, ptr %p642 ret i16 %cond643}644 645define i16 @test_multiuse_trunc_undef(i64 %x, ptr %p) {646; CHECK-LABEL: @test_multiuse_trunc_undef(647; CHECK-NEXT: [[CT:%.*]] = tail call range(i64 0, 65) i64 @llvm.cttz.i64(i64 [[X:%.*]], i1 false)648; CHECK-NEXT: [[CONV:%.*]] = trunc nuw nsw i64 [[CT]] to i16649; CHECK-NEXT: store i16 [[CONV]], ptr [[P:%.*]], align 2650; CHECK-NEXT: ret i16 [[CONV]]651;652 %ct = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)653 %conv = trunc i64 %ct to i16654 %tobool = icmp ne i64 %x, 0655 %cond = select i1 %tobool, i16 %conv, i16 64656 store i16 %conv, ptr %p657 ret i16 %cond658}659 660define i64 @test_pr128441(i64 %x, i64 %y) {661; CHECK-LABEL: @test_pr128441(662; CHECK-NEXT: [[XOR:%.*]] = xor i64 [[X:%.*]], [[Y:%.*]]663; CHECK-NEXT: [[SEL:%.*]] = call range(i64 0, 65) i64 @llvm.cttz.i64(i64 [[XOR]], i1 false)664; CHECK-NEXT: ret i64 [[SEL]]665;666 %iszero = icmp ne i64 %x, %y667 %xor = xor i64 %x, %y668 %cttz = call i64 @llvm.cttz.i64(i64 %xor, i1 true)669 %sel = select i1 %iszero, i64 %cttz, i64 64670 ret i64 %sel671}672 673define i64 @test_pr128441_commuted1(i64 %x, i64 %y) {674; CHECK-LABEL: @test_pr128441_commuted1(675; CHECK-NEXT: [[XOR:%.*]] = xor i64 [[Y:%.*]], [[X:%.*]]676; CHECK-NEXT: [[SEL:%.*]] = call range(i64 0, 65) i64 @llvm.cttz.i64(i64 [[XOR]], i1 false)677; CHECK-NEXT: ret i64 [[SEL]]678;679 %iszero = icmp ne i64 %x, %y680 %xor = xor i64 %y, %x681 %cttz = call i64 @llvm.cttz.i64(i64 %xor, i1 true)682 %sel = select i1 %iszero, i64 %cttz, i64 64683 ret i64 %sel684}685 686define i64 @test_pr128441_commuted2(i64 %x, i64 %y) {687; CHECK-LABEL: @test_pr128441_commuted2(688; CHECK-NEXT: [[XOR:%.*]] = xor i64 [[X:%.*]], [[Y:%.*]]689; CHECK-NEXT: [[SEL:%.*]] = call range(i64 0, 65) i64 @llvm.cttz.i64(i64 [[XOR]], i1 false)690; CHECK-NEXT: ret i64 [[SEL]]691;692 %iszero = icmp eq i64 %x, %y693 %xor = xor i64 %x, %y694 %cttz = call i64 @llvm.cttz.i64(i64 %xor, i1 true)695 %sel = select i1 %iszero, i64 64, i64 %cttz696 ret i64 %sel697}698 699define i64 @test_pr128441_commuted3_negative(i64 %x, i64 %y) {700; CHECK-LABEL: @test_pr128441_commuted3_negative(701; CHECK-NEXT: ret i64 64702;703 %iszero = icmp eq i64 %x, %y704 %xor = xor i64 %y, %x705 %cttz = call i64 @llvm.cttz.i64(i64 %xor, i1 true)706 %sel = select i1 %iszero, i64 %cttz, i64 64707 ret i64 %sel708}709 710define i64 @test_pr128441_commuted4_negative(i64 %x, i64 %y) {711; CHECK-LABEL: @test_pr128441_commuted4_negative(712; CHECK-NEXT: ret i64 64713;714 %iszero = icmp ne i64 %x, %y715 %xor = xor i64 %x, %y716 %cttz = call i64 @llvm.cttz.i64(i64 %xor, i1 true)717 %sel = select i1 %iszero, i64 64, i64 %cttz718 ret i64 %sel719}720 721declare i16 @llvm.ctlz.i16(i16, i1)722declare i32 @llvm.ctlz.i32(i32, i1)723declare i64 @llvm.ctlz.i64(i64, i1)724declare i128 @llvm.ctlz.i128(i128, i1)725declare <2 x i32> @llvm.ctlz.v2i32(<2 x i32>, i1)726declare i16 @llvm.cttz.i16(i16, i1)727declare i32 @llvm.cttz.i32(i32, i1)728declare i64 @llvm.cttz.i64(i64, i1)729declare i128 @llvm.cttz.i128(i128, i1)730declare <2 x i32> @llvm.cttz.v2i32(<2 x i32>, i1)731