1404 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefixes=X863; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefixes=X644 5;; Use cttz to test if we properly prove never-zero. There is a very6;; simple transform from cttz -> cttz_zero_undef if its operand is7;; known never zero.8declare i32 @llvm.cttz.i32(i32, i1)9declare i32 @llvm.uadd.sat.i32(i32, i32)10declare i32 @llvm.umax.i32(i32, i32)11declare i32 @llvm.umin.i32(i32, i32)12declare i32 @llvm.smin.i32(i32, i32)13declare <4 x i32> @llvm.smin.v4i32(<4 x i32>, <4 x i32>)14declare i32 @llvm.smax.i32(i32, i32)15declare <4 x i32> @llvm.smax.v4i32(<4 x i32>, <4 x i32>)16declare i32 @llvm.bswap.i32(i32)17declare i32 @llvm.bitreverse.i32(i32)18declare i32 @llvm.ctpop.i32(i32)19declare <4 x i32> @llvm.ctpop.v4i32(<4 x i32>)20declare i32 @llvm.abs.i32(i32, i1)21declare i32 @llvm.fshl.i32(i32, i32, i32)22declare i32 @llvm.fshr.i32(i32, i32, i32)23 24define i32 @or_known_nonzero(i32 %x) {25; X86-LABEL: or_known_nonzero:26; X86: # %bb.0:27; X86-NEXT: movl {{[0-9]+}}(%esp), %eax28; X86-NEXT: orl $1, %eax29; X86-NEXT: rep bsfl %eax, %eax30; X86-NEXT: retl31;32; X64-LABEL: or_known_nonzero:33; X64: # %bb.0:34; X64-NEXT: orl $1, %edi35; X64-NEXT: rep bsfl %edi, %eax36; X64-NEXT: retq37 %z = or i32 %x, 138 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)39 ret i32 %r40}41 42define i32 @or_maybe_zero(i32 %x, i32 %y) {43; X86-LABEL: or_maybe_zero:44; X86: # %bb.0:45; X86-NEXT: movl {{[0-9]+}}(%esp), %eax46; X86-NEXT: orl {{[0-9]+}}(%esp), %eax47; X86-NEXT: bsfl %eax, %ecx48; X86-NEXT: movl $32, %eax49; X86-NEXT: cmovnel %ecx, %eax50; X86-NEXT: retl51;52; X64-LABEL: or_maybe_zero:53; X64: # %bb.0:54; X64-NEXT: orl %esi, %edi55; X64-NEXT: movl $32, %eax56; X64-NEXT: rep bsfl %edi, %eax57; X64-NEXT: retq58 %z = or i32 %x, %y59 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)60 ret i32 %r61}62 63define i32 @select_known_nonzero(i1 %c, i32 %x) {64; X86-LABEL: select_known_nonzero:65; X86: # %bb.0:66; X86-NEXT: movl {{[0-9]+}}(%esp), %eax67; X86-NEXT: orl $1, %eax68; X86-NEXT: testb $1, {{[0-9]+}}(%esp)69; X86-NEXT: movl $122, %ecx70; X86-NEXT: cmovnel %eax, %ecx71; X86-NEXT: rep bsfl %ecx, %eax72; X86-NEXT: retl73;74; X64-LABEL: select_known_nonzero:75; X64: # %bb.0:76; X64-NEXT: orl $1, %esi77; X64-NEXT: testb $1, %dil78; X64-NEXT: movl $122, %eax79; X64-NEXT: cmovnel %esi, %eax80; X64-NEXT: rep bsfl %eax, %eax81; X64-NEXT: retq82 %y = or i32 %x, 183 %z = select i1 %c, i32 %y, i32 12284 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)85 ret i32 %r86}87 88define i32 @select_maybe_zero(i1 %c, i32 %x) {89; X86-LABEL: select_maybe_zero:90; X86: # %bb.0:91; X86-NEXT: movl {{[0-9]+}}(%esp), %eax92; X86-NEXT: orl $1, %eax93; X86-NEXT: xorl %ecx, %ecx94; X86-NEXT: testb $1, {{[0-9]+}}(%esp)95; X86-NEXT: cmovnel %eax, %ecx96; X86-NEXT: bsfl %ecx, %ecx97; X86-NEXT: movl $32, %eax98; X86-NEXT: cmovnel %ecx, %eax99; X86-NEXT: retl100;101; X64-LABEL: select_maybe_zero:102; X64: # %bb.0:103; X64-NEXT: orl $1, %esi104; X64-NEXT: xorl %ecx, %ecx105; X64-NEXT: testb $1, %dil106; X64-NEXT: cmovnel %esi, %ecx107; X64-NEXT: movl $32, %eax108; X64-NEXT: rep bsfl %ecx, %eax109; X64-NEXT: retq110 %y = or i32 %x, 1111 %z = select i1 %c, i32 %y, i32 0112 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)113 ret i32 %r114}115 116define i32 @shl_known_nonzero_1s_bit_set(i32 %x) {117; X86-LABEL: shl_known_nonzero_1s_bit_set:118; X86: # %bb.0:119; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx120; X86-NEXT: movl $123, %eax121; X86-NEXT: shll %cl, %eax122; X86-NEXT: rep bsfl %eax, %eax123; X86-NEXT: retl124;125; X64-LABEL: shl_known_nonzero_1s_bit_set:126; X64: # %bb.0:127; X64-NEXT: movl %edi, %ecx128; X64-NEXT: movl $123, %eax129; X64-NEXT: # kill: def $cl killed $cl killed $ecx130; X64-NEXT: shll %cl, %eax131; X64-NEXT: rep bsfl %eax, %eax132; X64-NEXT: retq133 %z = shl i32 123, %x134 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)135 ret i32 %r136}137 138define i32 @shl_known_nonzero_nsw(i32 %x, i32 %yy) {139; X86-LABEL: shl_known_nonzero_nsw:140; X86: # %bb.0:141; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx142; X86-NEXT: movl $256, %eax # imm = 0x100143; X86-NEXT: orl {{[0-9]+}}(%esp), %eax144; X86-NEXT: shll %cl, %eax145; X86-NEXT: rep bsfl %eax, %eax146; X86-NEXT: retl147;148; X64-LABEL: shl_known_nonzero_nsw:149; X64: # %bb.0:150; X64-NEXT: movl %edi, %ecx151; X64-NEXT: orl $256, %esi # imm = 0x100152; X64-NEXT: # kill: def $cl killed $cl killed $ecx153; X64-NEXT: shll %cl, %esi154; X64-NEXT: rep bsfl %esi, %eax155; X64-NEXT: retq156 %y = or i32 %yy, 256157 %z = shl nsw i32 %y, %x158 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)159 ret i32 %r160}161 162define i32 @shl_known_nonzero_nuw(i32 %x, i32 %yy) {163; X86-LABEL: shl_known_nonzero_nuw:164; X86: # %bb.0:165; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx166; X86-NEXT: movl $256, %eax # imm = 0x100167; X86-NEXT: orl {{[0-9]+}}(%esp), %eax168; X86-NEXT: shll %cl, %eax169; X86-NEXT: rep bsfl %eax, %eax170; X86-NEXT: retl171;172; X64-LABEL: shl_known_nonzero_nuw:173; X64: # %bb.0:174; X64-NEXT: movl %edi, %ecx175; X64-NEXT: orl $256, %esi # imm = 0x100176; X64-NEXT: # kill: def $cl killed $cl killed $ecx177; X64-NEXT: shll %cl, %esi178; X64-NEXT: rep bsfl %esi, %eax179; X64-NEXT: retq180 %y = or i32 %yy, 256181 %z = shl nuw i32 %y, %x182 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)183 ret i32 %r184}185 186define i32 @shl_maybe_zero(i32 %x, i32 %y) {187; X86-LABEL: shl_maybe_zero:188; X86: # %bb.0:189; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx190; X86-NEXT: movl {{[0-9]+}}(%esp), %eax191; X86-NEXT: shll %cl, %eax192; X86-NEXT: bsfl %eax, %ecx193; X86-NEXT: movl $32, %eax194; X86-NEXT: cmovnel %ecx, %eax195; X86-NEXT: retl196;197; X64-LABEL: shl_maybe_zero:198; X64: # %bb.0:199; X64-NEXT: movl %edi, %ecx200; X64-NEXT: # kill: def $cl killed $cl killed $ecx201; X64-NEXT: shll %cl, %esi202; X64-NEXT: movl $32, %eax203; X64-NEXT: rep bsfl %esi, %eax204; X64-NEXT: retq205 %z = shl nuw nsw i32 %y, %x206 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)207 ret i32 %r208}209 210define i32 @uaddsat_known_nonzero(i32 %x) {211; X86-LABEL: uaddsat_known_nonzero:212; X86: # %bb.0:213; X86-NEXT: movl {{[0-9]+}}(%esp), %eax214; X86-NEXT: incl %eax215; X86-NEXT: movl $-1, %ecx216; X86-NEXT: cmovnel %eax, %ecx217; X86-NEXT: rep bsfl %ecx, %eax218; X86-NEXT: retl219;220; X64-LABEL: uaddsat_known_nonzero:221; X64: # %bb.0:222; X64-NEXT: incl %edi223; X64-NEXT: movl $-1, %eax224; X64-NEXT: cmovnel %edi, %eax225; X64-NEXT: rep bsfl %eax, %eax226; X64-NEXT: retq227 %z = call i32 @llvm.uadd.sat.i32(i32 %x, i32 1)228 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)229 ret i32 %r230}231 232define i32 @uaddsat_maybe_zero(i32 %x, i32 %y) {233; X86-LABEL: uaddsat_maybe_zero:234; X86: # %bb.0:235; X86-NEXT: movl {{[0-9]+}}(%esp), %eax236; X86-NEXT: addl {{[0-9]+}}(%esp), %eax237; X86-NEXT: movl $-1, %ecx238; X86-NEXT: cmovael %eax, %ecx239; X86-NEXT: bsfl %ecx, %ecx240; X86-NEXT: movl $32, %eax241; X86-NEXT: cmovnel %ecx, %eax242; X86-NEXT: retl243;244; X64-LABEL: uaddsat_maybe_zero:245; X64: # %bb.0:246; X64-NEXT: addl %esi, %edi247; X64-NEXT: movl $-1, %ecx248; X64-NEXT: cmovael %edi, %ecx249; X64-NEXT: movl $32, %eax250; X64-NEXT: rep bsfl %ecx, %eax251; X64-NEXT: retq252 %z = call i32 @llvm.uadd.sat.i32(i32 %x, i32 %y)253 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)254 ret i32 %r255}256 257define i32 @umax_known_nonzero(i32 %x, i32 %y) {258; X86-LABEL: umax_known_nonzero:259; X86: # %bb.0:260; X86-NEXT: movl {{[0-9]+}}(%esp), %eax261; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx262; X86-NEXT: movl $4, %edx263; X86-NEXT: shll %cl, %edx264; X86-NEXT: cmpl %edx, %eax265; X86-NEXT: cmoval %eax, %edx266; X86-NEXT: rep bsfl %edx, %eax267; X86-NEXT: retl268;269; X64-LABEL: umax_known_nonzero:270; X64: # %bb.0:271; X64-NEXT: movl %esi, %ecx272; X64-NEXT: movl $4, %eax273; X64-NEXT: # kill: def $cl killed $cl killed $ecx274; X64-NEXT: shll %cl, %eax275; X64-NEXT: cmpl %eax, %edi276; X64-NEXT: cmoval %edi, %eax277; X64-NEXT: rep bsfl %eax, %eax278; X64-NEXT: retq279 %yy = shl nuw i32 4, %y280 %z = call i32 @llvm.umax.i32(i32 %x, i32 %yy)281 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)282 ret i32 %r283}284 285define i32 @umax_maybe_zero(i32 %x, i32 %y) {286; X86-LABEL: umax_maybe_zero:287; X86: # %bb.0:288; X86-NEXT: movl {{[0-9]+}}(%esp), %eax289; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx290; X86-NEXT: cmpl %eax, %ecx291; X86-NEXT: cmoval %ecx, %eax292; X86-NEXT: bsfl %eax, %ecx293; X86-NEXT: movl $32, %eax294; X86-NEXT: cmovnel %ecx, %eax295; X86-NEXT: retl296;297; X64-LABEL: umax_maybe_zero:298; X64: # %bb.0:299; X64-NEXT: cmpl %esi, %edi300; X64-NEXT: cmoval %edi, %esi301; X64-NEXT: movl $32, %eax302; X64-NEXT: rep bsfl %esi, %eax303; X64-NEXT: retq304 %z = call i32 @llvm.umax.i32(i32 %x, i32 %y)305 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)306 ret i32 %r307}308 309define i32 @umin_known_nonzero(i32 %xx, i32 %yy) {310; X86-LABEL: umin_known_nonzero:311; X86: # %bb.0:312; X86-NEXT: movl {{[0-9]+}}(%esp), %eax313; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx314; X86-NEXT: movl $4, %edx315; X86-NEXT: shll %cl, %edx316; X86-NEXT: addl $4, %eax317; X86-NEXT: cmpl %eax, %edx318; X86-NEXT: cmovbl %edx, %eax319; X86-NEXT: rep bsfl %eax, %eax320; X86-NEXT: retl321;322; X64-LABEL: umin_known_nonzero:323; X64: # %bb.0:324; X64-NEXT: movl %edi, %ecx325; X64-NEXT: movl $4, %eax326; X64-NEXT: # kill: def $cl killed $cl killed $ecx327; X64-NEXT: shll %cl, %eax328; X64-NEXT: addl $4, %esi329; X64-NEXT: cmpl %esi, %eax330; X64-NEXT: cmovbl %eax, %esi331; X64-NEXT: rep bsfl %esi, %eax332; X64-NEXT: retq333 %x = shl nuw i32 4, %xx334 %y = add nuw nsw i32 %yy, 4335 %z = call i32 @llvm.umin.i32(i32 %x, i32 %y)336 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)337 ret i32 %r338}339 340define i32 @umin_maybe_zero(i32 %x, i32 %y) {341; X86-LABEL: umin_maybe_zero:342; X86: # %bb.0:343; X86-NEXT: movl {{[0-9]+}}(%esp), %eax344; X86-NEXT: cmpl $54, %eax345; X86-NEXT: movl $54, %ecx346; X86-NEXT: cmovbl %eax, %ecx347; X86-NEXT: bsfl %ecx, %ecx348; X86-NEXT: movl $32, %eax349; X86-NEXT: cmovnel %ecx, %eax350; X86-NEXT: retl351;352; X64-LABEL: umin_maybe_zero:353; X64: # %bb.0:354; X64-NEXT: cmpl $54, %edi355; X64-NEXT: movl $54, %ecx356; X64-NEXT: cmovbl %edi, %ecx357; X64-NEXT: movl $32, %eax358; X64-NEXT: rep bsfl %ecx, %eax359; X64-NEXT: retq360 %z = call i32 @llvm.umin.i32(i32 %x, i32 54)361 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)362 ret i32 %r363}364 365define i32 @smin_known_nonzero(i32 %xx, i32 %yy) {366; X86-LABEL: smin_known_nonzero:367; X86: # %bb.0:368; X86-NEXT: movl {{[0-9]+}}(%esp), %eax369; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx370; X86-NEXT: movl $4, %edx371; X86-NEXT: shll %cl, %edx372; X86-NEXT: addl $4, %eax373; X86-NEXT: cmpl %eax, %edx374; X86-NEXT: cmovll %edx, %eax375; X86-NEXT: rep bsfl %eax, %eax376; X86-NEXT: retl377;378; X64-LABEL: smin_known_nonzero:379; X64: # %bb.0:380; X64-NEXT: movl %edi, %ecx381; X64-NEXT: movl $4, %eax382; X64-NEXT: # kill: def $cl killed $cl killed $ecx383; X64-NEXT: shll %cl, %eax384; X64-NEXT: addl $4, %esi385; X64-NEXT: cmpl %esi, %eax386; X64-NEXT: cmovll %eax, %esi387; X64-NEXT: rep bsfl %esi, %eax388; X64-NEXT: retq389 %x = shl nuw i32 4, %xx390 %y = add nuw nsw i32 %yy, 4391 %z = call i32 @llvm.smin.i32(i32 %x, i32 %y)392 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)393 ret i32 %r394}395 396define i32 @smin_known_zero(i32 %x, i32 %y) {397; X86-LABEL: smin_known_zero:398; X86: # %bb.0:399; X86-NEXT: movl {{[0-9]+}}(%esp), %eax400; X86-NEXT: cmpl $-54, %eax401; X86-NEXT: movl $-54, %ecx402; X86-NEXT: cmovll %eax, %ecx403; X86-NEXT: rep bsfl %ecx, %eax404; X86-NEXT: retl405;406; X64-LABEL: smin_known_zero:407; X64: # %bb.0:408; X64-NEXT: cmpl $-54, %edi409; X64-NEXT: movl $-54, %eax410; X64-NEXT: cmovll %edi, %eax411; X64-NEXT: rep bsfl %eax, %eax412; X64-NEXT: retq413 %z = call i32 @llvm.smin.i32(i32 %x, i32 -54)414 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)415 ret i32 %r416}417 418define <4 x i32> @smin_known_zero_vec(<4 x i32> %x, <4 x i32> %y) {419; X86-LABEL: smin_known_zero_vec:420; X86: # %bb.0:421; X86-NEXT: movdqa {{.*#+}} xmm1 = [4294967242,4294967273,4294967284,4294967295]422; X86-NEXT: movdqa %xmm1, %xmm2423; X86-NEXT: pcmpgtd %xmm0, %xmm2424; X86-NEXT: pand %xmm2, %xmm0425; X86-NEXT: pandn %xmm1, %xmm2426; X86-NEXT: por %xmm2, %xmm0427; X86-NEXT: pcmpeqd %xmm1, %xmm1428; X86-NEXT: paddd %xmm0, %xmm1429; X86-NEXT: pand %xmm1, %xmm0430; X86-NEXT: pxor %xmm1, %xmm1431; X86-NEXT: pcmpeqd %xmm1, %xmm0432; X86-NEXT: psrld $31, %xmm0433; X86-NEXT: retl434;435; X64-LABEL: smin_known_zero_vec:436; X64: # %bb.0:437; X64-NEXT: vpminsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0438; X64-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1439; X64-NEXT: vpaddd %xmm1, %xmm0, %xmm1440; X64-NEXT: vpand %xmm1, %xmm0, %xmm0441; X64-NEXT: vpxor %xmm1, %xmm1, %xmm1442; X64-NEXT: vpcmpeqd %xmm1, %xmm0, %xmm0443; X64-NEXT: vpsrld $31, %xmm0, %xmm0444; X64-NEXT: retq445 %z = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %x, <4 x i32> <i32 -54, i32 -23, i32 -12, i32 -1>)446 %r = call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %z)447 %3 = icmp eq <4 x i32> %r, <i32 1, i32 1, i32 1, i32 1>448 %ret = zext <4 x i1> %3 to <4 x i32>449 ret <4 x i32> %ret450}451 452define i32 @smin_maybe_zero(i32 %x, i32 %y) {453; X86-LABEL: smin_maybe_zero:454; X86: # %bb.0:455; X86-NEXT: movl {{[0-9]+}}(%esp), %eax456; X86-NEXT: cmpl $54, %eax457; X86-NEXT: movl $54, %ecx458; X86-NEXT: cmovll %eax, %ecx459; X86-NEXT: bsfl %ecx, %ecx460; X86-NEXT: movl $32, %eax461; X86-NEXT: cmovnel %ecx, %eax462; X86-NEXT: retl463;464; X64-LABEL: smin_maybe_zero:465; X64: # %bb.0:466; X64-NEXT: cmpl $54, %edi467; X64-NEXT: movl $54, %ecx468; X64-NEXT: cmovll %edi, %ecx469; X64-NEXT: movl $32, %eax470; X64-NEXT: rep bsfl %ecx, %eax471; X64-NEXT: retq472 %z = call i32 @llvm.smin.i32(i32 %x, i32 54)473 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)474 ret i32 %r475}476 477define i32 @smax_known_nonzero(i32 %xx, i32 %yy) {478; X86-LABEL: smax_known_nonzero:479; X86: # %bb.0:480; X86-NEXT: movl {{[0-9]+}}(%esp), %eax481; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx482; X86-NEXT: movl $4, %edx483; X86-NEXT: shll %cl, %edx484; X86-NEXT: addl $4, %eax485; X86-NEXT: cmpl %eax, %edx486; X86-NEXT: cmovgl %edx, %eax487; X86-NEXT: rep bsfl %eax, %eax488; X86-NEXT: retl489;490; X64-LABEL: smax_known_nonzero:491; X64: # %bb.0:492; X64-NEXT: movl %edi, %ecx493; X64-NEXT: movl $4, %eax494; X64-NEXT: # kill: def $cl killed $cl killed $ecx495; X64-NEXT: shll %cl, %eax496; X64-NEXT: addl $4, %esi497; X64-NEXT: cmpl %esi, %eax498; X64-NEXT: cmovgl %eax, %esi499; X64-NEXT: rep bsfl %esi, %eax500; X64-NEXT: retq501 %x = shl nuw i32 4, %xx502 %y = add nuw nsw i32 %yy, 4503 %z = call i32 @llvm.smax.i32(i32 %x, i32 %y)504 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)505 ret i32 %r506}507 508define i32 @smax_maybe_zero(i32 %x, i32 %y) {509; X86-LABEL: smax_maybe_zero:510; X86: # %bb.0:511; X86-NEXT: movl {{[0-9]+}}(%esp), %eax512; X86-NEXT: cmpl $55, %eax513; X86-NEXT: movl $54, %ecx514; X86-NEXT: cmovgel %eax, %ecx515; X86-NEXT: rep bsfl %ecx, %eax516; X86-NEXT: retl517;518; X64-LABEL: smax_maybe_zero:519; X64: # %bb.0:520; X64-NEXT: cmpl $55, %edi521; X64-NEXT: movl $54, %eax522; X64-NEXT: cmovgel %edi, %eax523; X64-NEXT: rep bsfl %eax, %eax524; X64-NEXT: retq525 %z = call i32 @llvm.smax.i32(i32 %x, i32 54)526 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)527 ret i32 %r528}529 530define <4 x i32> @smax_known_zero_vec(<4 x i32> %x, <4 x i32> %y) {531; X86-LABEL: smax_known_zero_vec:532; X86: # %bb.0:533; X86-NEXT: movdqa {{.*#+}} xmm1 = [54,23,12,1]534; X86-NEXT: movdqa %xmm0, %xmm2535; X86-NEXT: pcmpgtd %xmm1, %xmm2536; X86-NEXT: pand %xmm2, %xmm0537; X86-NEXT: pandn %xmm1, %xmm2538; X86-NEXT: por %xmm2, %xmm0539; X86-NEXT: pcmpeqd %xmm1, %xmm1540; X86-NEXT: paddd %xmm0, %xmm1541; X86-NEXT: pand %xmm1, %xmm0542; X86-NEXT: pxor %xmm1, %xmm1543; X86-NEXT: pcmpeqd %xmm1, %xmm0544; X86-NEXT: psrld $31, %xmm0545; X86-NEXT: retl546;547; X64-LABEL: smax_known_zero_vec:548; X64: # %bb.0:549; X64-NEXT: vpmaxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0550; X64-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1551; X64-NEXT: vpaddd %xmm1, %xmm0, %xmm1552; X64-NEXT: vpand %xmm1, %xmm0, %xmm0553; X64-NEXT: vpxor %xmm1, %xmm1, %xmm1554; X64-NEXT: vpcmpeqd %xmm1, %xmm0, %xmm0555; X64-NEXT: vpsrld $31, %xmm0, %xmm0556; X64-NEXT: retq557 %z = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %x, <4 x i32> <i32 54, i32 23, i32 12, i32 1>)558 %r = call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %z)559 %3 = icmp eq <4 x i32> %r, <i32 1, i32 1, i32 1, i32 1>560 %ret = zext <4 x i1> %3 to <4 x i32>561 ret <4 x i32> %ret562}563 564define i32 @smax_known_zero(i32 %x, i32 %y) {565; X86-LABEL: smax_known_zero:566; X86: # %bb.0:567; X86-NEXT: movl {{[0-9]+}}(%esp), %eax568; X86-NEXT: testl %eax, %eax569; X86-NEXT: movl $-1, %ecx570; X86-NEXT: cmovnsl %eax, %ecx571; X86-NEXT: bsfl %ecx, %ecx572; X86-NEXT: movl $32, %eax573; X86-NEXT: cmovnel %ecx, %eax574; X86-NEXT: retl575;576; X64-LABEL: smax_known_zero:577; X64: # %bb.0:578; X64-NEXT: testl %edi, %edi579; X64-NEXT: movl $-1, %ecx580; X64-NEXT: cmovnsl %edi, %ecx581; X64-NEXT: movl $32, %eax582; X64-NEXT: rep bsfl %ecx, %eax583; X64-NEXT: retq584 %z = call i32 @llvm.smax.i32(i32 %x, i32 -1)585 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)586 ret i32 %r587}588 589define i32 @rotr_known_nonzero(i32 %xx, i32 %y) {590; X86-LABEL: rotr_known_nonzero:591; X86: # %bb.0:592; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx593; X86-NEXT: movl $256, %eax # imm = 0x100594; X86-NEXT: orl {{[0-9]+}}(%esp), %eax595; X86-NEXT: rorl %cl, %eax596; X86-NEXT: rep bsfl %eax, %eax597; X86-NEXT: retl598;599; X64-LABEL: rotr_known_nonzero:600; X64: # %bb.0:601; X64-NEXT: movl %esi, %ecx602; X64-NEXT: orl $256, %edi # imm = 0x100603; X64-NEXT: # kill: def $cl killed $cl killed $ecx604; X64-NEXT: rorl %cl, %edi605; X64-NEXT: rep bsfl %edi, %eax606; X64-NEXT: retq607 %x = or i32 %xx, 256608 %shr = lshr i32 %x, %y609 %sub = sub i32 32, %y610 %shl = shl i32 %x, %sub611 %z = or i32 %shl, %shr612 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)613 ret i32 %r614}615 616define i32 @rotr_maybe_zero(i32 %x, i32 %y) {617; X86-LABEL: rotr_maybe_zero:618; X86: # %bb.0:619; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx620; X86-NEXT: movl {{[0-9]+}}(%esp), %eax621; X86-NEXT: rorl %cl, %eax622; X86-NEXT: bsfl %eax, %ecx623; X86-NEXT: movl $32, %eax624; X86-NEXT: cmovnel %ecx, %eax625; X86-NEXT: retl626;627; X64-LABEL: rotr_maybe_zero:628; X64: # %bb.0:629; X64-NEXT: movl %esi, %ecx630; X64-NEXT: # kill: def $cl killed $cl killed $ecx631; X64-NEXT: rorl %cl, %edi632; X64-NEXT: movl $32, %eax633; X64-NEXT: rep bsfl %edi, %eax634; X64-NEXT: retq635 %shr = lshr i32 %x, %y636 %sub = sub i32 32, %y637 %shl = shl i32 %x, %sub638 %z = or i32 %shl, %shr639 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)640 ret i32 %r641}642 643define i32 @rotr_with_fshr_known_nonzero(i32 %xx, i32 %y) {644; X86-LABEL: rotr_with_fshr_known_nonzero:645; X86: # %bb.0:646; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx647; X86-NEXT: movl $256, %eax # imm = 0x100648; X86-NEXT: orl {{[0-9]+}}(%esp), %eax649; X86-NEXT: rorl %cl, %eax650; X86-NEXT: rep bsfl %eax, %eax651; X86-NEXT: retl652;653; X64-LABEL: rotr_with_fshr_known_nonzero:654; X64: # %bb.0:655; X64-NEXT: movl %esi, %ecx656; X64-NEXT: orl $256, %edi # imm = 0x100657; X64-NEXT: # kill: def $cl killed $cl killed $ecx658; X64-NEXT: rorl %cl, %edi659; X64-NEXT: rep bsfl %edi, %eax660; X64-NEXT: retq661 %x = or i32 %xx, 256662 %z = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 %y)663 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)664 ret i32 %r665}666 667define i32 @rotr_with_fshr_maybe_zero(i32 %x, i32 %y) {668; X86-LABEL: rotr_with_fshr_maybe_zero:669; X86: # %bb.0:670; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx671; X86-NEXT: movl {{[0-9]+}}(%esp), %eax672; X86-NEXT: rorl %cl, %eax673; X86-NEXT: bsfl %eax, %ecx674; X86-NEXT: movl $32, %eax675; X86-NEXT: cmovnel %ecx, %eax676; X86-NEXT: retl677;678; X64-LABEL: rotr_with_fshr_maybe_zero:679; X64: # %bb.0:680; X64-NEXT: movl %esi, %ecx681; X64-NEXT: # kill: def $cl killed $cl killed $ecx682; X64-NEXT: rorl %cl, %edi683; X64-NEXT: movl $32, %eax684; X64-NEXT: rep bsfl %edi, %eax685; X64-NEXT: retq686 %z = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 %y)687 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)688 ret i32 %r689}690 691define i32 @rotl_known_nonzero(i32 %xx, i32 %y) {692; X86-LABEL: rotl_known_nonzero:693; X86: # %bb.0:694; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx695; X86-NEXT: movl $256, %eax # imm = 0x100696; X86-NEXT: orl {{[0-9]+}}(%esp), %eax697; X86-NEXT: roll %cl, %eax698; X86-NEXT: rep bsfl %eax, %eax699; X86-NEXT: retl700;701; X64-LABEL: rotl_known_nonzero:702; X64: # %bb.0:703; X64-NEXT: movl %esi, %ecx704; X64-NEXT: orl $256, %edi # imm = 0x100705; X64-NEXT: # kill: def $cl killed $cl killed $ecx706; X64-NEXT: roll %cl, %edi707; X64-NEXT: rep bsfl %edi, %eax708; X64-NEXT: retq709 %x = or i32 %xx, 256710 %shl = shl i32 %x, %y711 %sub = sub i32 32, %y712 %shr = lshr i32 %x, %sub713 %z = or i32 %shr, %shl714 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)715 ret i32 %r716}717 718define i32 @rotl_maybe_zero(i32 %x, i32 %y) {719; X86-LABEL: rotl_maybe_zero:720; X86: # %bb.0:721; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx722; X86-NEXT: movl {{[0-9]+}}(%esp), %eax723; X86-NEXT: roll %cl, %eax724; X86-NEXT: bsfl %eax, %ecx725; X86-NEXT: movl $32, %eax726; X86-NEXT: cmovnel %ecx, %eax727; X86-NEXT: retl728;729; X64-LABEL: rotl_maybe_zero:730; X64: # %bb.0:731; X64-NEXT: movl %esi, %ecx732; X64-NEXT: # kill: def $cl killed $cl killed $ecx733; X64-NEXT: roll %cl, %edi734; X64-NEXT: movl $32, %eax735; X64-NEXT: rep bsfl %edi, %eax736; X64-NEXT: retq737 %shl = shl i32 %x, %y738 %sub = sub i32 32, %y739 %shr = lshr i32 %x, %sub740 %z = or i32 %shr, %shl741 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)742 ret i32 %r743}744 745define i32 @rotl_with_fshl_known_nonzero(i32 %xx, i32 %y) {746; X86-LABEL: rotl_with_fshl_known_nonzero:747; X86: # %bb.0:748; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx749; X86-NEXT: movl $256, %eax # imm = 0x100750; X86-NEXT: orl {{[0-9]+}}(%esp), %eax751; X86-NEXT: roll %cl, %eax752; X86-NEXT: rep bsfl %eax, %eax753; X86-NEXT: retl754;755; X64-LABEL: rotl_with_fshl_known_nonzero:756; X64: # %bb.0:757; X64-NEXT: movl %esi, %ecx758; X64-NEXT: orl $256, %edi # imm = 0x100759; X64-NEXT: # kill: def $cl killed $cl killed $ecx760; X64-NEXT: roll %cl, %edi761; X64-NEXT: rep bsfl %edi, %eax762; X64-NEXT: retq763 %x = or i32 %xx, 256764 %z = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 %y)765 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)766 ret i32 %r767}768 769define i32 @rotl_with_fshl_maybe_zero(i32 %x, i32 %y) {770; X86-LABEL: rotl_with_fshl_maybe_zero:771; X86: # %bb.0:772; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx773; X86-NEXT: movl {{[0-9]+}}(%esp), %eax774; X86-NEXT: roll %cl, %eax775; X86-NEXT: bsfl %eax, %ecx776; X86-NEXT: movl $32, %eax777; X86-NEXT: cmovnel %ecx, %eax778; X86-NEXT: retl779;780; X64-LABEL: rotl_with_fshl_maybe_zero:781; X64: # %bb.0:782; X64-NEXT: movl %esi, %ecx783; X64-NEXT: # kill: def $cl killed $cl killed $ecx784; X64-NEXT: roll %cl, %edi785; X64-NEXT: movl $32, %eax786; X64-NEXT: rep bsfl %edi, %eax787; X64-NEXT: retq788 %z = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 %y)789 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)790 ret i32 %r791}792 793define i32 @sra_known_nonzero_sign_bit_set(i32 %x) {794; X86-LABEL: sra_known_nonzero_sign_bit_set:795; X86: # %bb.0:796; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx797; X86-NEXT: movl $-2147360405, %eax # imm = 0x8001E16B798; X86-NEXT: sarl %cl, %eax799; X86-NEXT: rep bsfl %eax, %eax800; X86-NEXT: retl801;802; X64-LABEL: sra_known_nonzero_sign_bit_set:803; X64: # %bb.0:804; X64-NEXT: movl %edi, %ecx805; X64-NEXT: movl $-2147360405, %eax # imm = 0x8001E16B806; X64-NEXT: # kill: def $cl killed $cl killed $ecx807; X64-NEXT: sarl %cl, %eax808; X64-NEXT: rep bsfl %eax, %eax809; X64-NEXT: retq810 %z = ashr i32 2147606891, %x811 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)812 ret i32 %r813}814 815define i32 @sra_known_nonzero_exact(i32 %x, i32 %yy) {816; X86-LABEL: sra_known_nonzero_exact:817; X86: # %bb.0:818; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx819; X86-NEXT: movl $256, %eax # imm = 0x100820; X86-NEXT: orl {{[0-9]+}}(%esp), %eax821; X86-NEXT: sarl %cl, %eax822; X86-NEXT: rep bsfl %eax, %eax823; X86-NEXT: retl824;825; X64-LABEL: sra_known_nonzero_exact:826; X64: # %bb.0:827; X64-NEXT: movl %edi, %ecx828; X64-NEXT: orl $256, %esi # imm = 0x100829; X64-NEXT: # kill: def $cl killed $cl killed $ecx830; X64-NEXT: sarl %cl, %esi831; X64-NEXT: rep bsfl %esi, %eax832; X64-NEXT: retq833 %y = or i32 %yy, 256834 %z = ashr exact i32 %y, %x835 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)836 ret i32 %r837}838 839define i32 @sra_maybe_zero(i32 %x, i32 %y) {840; X86-LABEL: sra_maybe_zero:841; X86: # %bb.0:842; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx843; X86-NEXT: movl {{[0-9]+}}(%esp), %eax844; X86-NEXT: sarl %cl, %eax845; X86-NEXT: bsfl %eax, %ecx846; X86-NEXT: movl $32, %eax847; X86-NEXT: cmovnel %ecx, %eax848; X86-NEXT: retl849;850; X64-LABEL: sra_maybe_zero:851; X64: # %bb.0:852; X64-NEXT: movl %edi, %ecx853; X64-NEXT: # kill: def $cl killed $cl killed $ecx854; X64-NEXT: sarl %cl, %esi855; X64-NEXT: movl $32, %eax856; X64-NEXT: rep bsfl %esi, %eax857; X64-NEXT: retq858 %z = ashr exact i32 %y, %x859 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)860 ret i32 %r861}862 863define i32 @srl_known_nonzero_sign_bit_set(i32 %x) {864; X86-LABEL: srl_known_nonzero_sign_bit_set:865; X86: # %bb.0:866; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx867; X86-NEXT: movl $-2147360405, %eax # imm = 0x8001E16B868; X86-NEXT: shrl %cl, %eax869; X86-NEXT: rep bsfl %eax, %eax870; X86-NEXT: retl871;872; X64-LABEL: srl_known_nonzero_sign_bit_set:873; X64: # %bb.0:874; X64-NEXT: movl %edi, %ecx875; X64-NEXT: movl $-2147360405, %eax # imm = 0x8001E16B876; X64-NEXT: # kill: def $cl killed $cl killed $ecx877; X64-NEXT: shrl %cl, %eax878; X64-NEXT: rep bsfl %eax, %eax879; X64-NEXT: retq880 %z = lshr i32 2147606891, %x881 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)882 ret i32 %r883}884 885define i32 @srl_known_nonzero_exact(i32 %x, i32 %yy) {886; X86-LABEL: srl_known_nonzero_exact:887; X86: # %bb.0:888; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx889; X86-NEXT: movl $256, %eax # imm = 0x100890; X86-NEXT: orl {{[0-9]+}}(%esp), %eax891; X86-NEXT: shrl %cl, %eax892; X86-NEXT: rep bsfl %eax, %eax893; X86-NEXT: retl894;895; X64-LABEL: srl_known_nonzero_exact:896; X64: # %bb.0:897; X64-NEXT: movl %edi, %ecx898; X64-NEXT: orl $256, %esi # imm = 0x100899; X64-NEXT: # kill: def $cl killed $cl killed $ecx900; X64-NEXT: shrl %cl, %esi901; X64-NEXT: rep bsfl %esi, %eax902; X64-NEXT: retq903 %y = or i32 %yy, 256904 %z = lshr exact i32 %y, %x905 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)906 ret i32 %r907}908 909define i32 @srl_maybe_zero(i32 %x, i32 %y) {910; X86-LABEL: srl_maybe_zero:911; X86: # %bb.0:912; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx913; X86-NEXT: movl {{[0-9]+}}(%esp), %eax914; X86-NEXT: shrl %cl, %eax915; X86-NEXT: bsfl %eax, %ecx916; X86-NEXT: movl $32, %eax917; X86-NEXT: cmovnel %ecx, %eax918; X86-NEXT: retl919;920; X64-LABEL: srl_maybe_zero:921; X64: # %bb.0:922; X64-NEXT: movl %edi, %ecx923; X64-NEXT: # kill: def $cl killed $cl killed $ecx924; X64-NEXT: shrl %cl, %esi925; X64-NEXT: movl $32, %eax926; X64-NEXT: rep bsfl %esi, %eax927; X64-NEXT: retq928 %z = lshr exact i32 %y, %x929 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)930 ret i32 %r931}932 933define i32 @udiv_known_nonzero(i32 %xx, i32 %y) {934; X86-LABEL: udiv_known_nonzero:935; X86: # %bb.0:936; X86-NEXT: movl {{[0-9]+}}(%esp), %eax937; X86-NEXT: orl $64, %eax938; X86-NEXT: xorl %edx, %edx939; X86-NEXT: divl {{[0-9]+}}(%esp)940; X86-NEXT: rep bsfl %eax, %eax941; X86-NEXT: retl942;943; X64-LABEL: udiv_known_nonzero:944; X64: # %bb.0:945; X64-NEXT: movl %edi, %eax946; X64-NEXT: orl $64, %eax947; X64-NEXT: xorl %edx, %edx948; X64-NEXT: divl %esi949; X64-NEXT: rep bsfl %eax, %eax950; X64-NEXT: retq951 %x = or i32 %xx, 64952 %z = udiv exact i32 %x, %y953 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)954 ret i32 %r955}956 957define i32 @udiv_maybe_zero(i32 %x, i32 %y) {958; X86-LABEL: udiv_maybe_zero:959; X86: # %bb.0:960; X86-NEXT: movl {{[0-9]+}}(%esp), %eax961; X86-NEXT: xorl %edx, %edx962; X86-NEXT: divl {{[0-9]+}}(%esp)963; X86-NEXT: bsfl %eax, %ecx964; X86-NEXT: movl $32, %eax965; X86-NEXT: cmovnel %ecx, %eax966; X86-NEXT: retl967;968; X64-LABEL: udiv_maybe_zero:969; X64: # %bb.0:970; X64-NEXT: movl %edi, %eax971; X64-NEXT: xorl %edx, %edx972; X64-NEXT: divl %esi973; X64-NEXT: movl $32, %ecx974; X64-NEXT: rep bsfl %eax, %ecx975; X64-NEXT: movl %ecx, %eax976; X64-NEXT: retq977 %z = udiv exact i32 %x, %y978 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)979 ret i32 %r980}981 982define i32 @sdiv_known_nonzero(i32 %xx, i32 %y) {983; X86-LABEL: sdiv_known_nonzero:984; X86: # %bb.0:985; X86-NEXT: movl {{[0-9]+}}(%esp), %eax986; X86-NEXT: orl $64, %eax987; X86-NEXT: cltd988; X86-NEXT: idivl {{[0-9]+}}(%esp)989; X86-NEXT: rep bsfl %eax, %eax990; X86-NEXT: retl991;992; X64-LABEL: sdiv_known_nonzero:993; X64: # %bb.0:994; X64-NEXT: movl %edi, %eax995; X64-NEXT: orl $64, %eax996; X64-NEXT: cltd997; X64-NEXT: idivl %esi998; X64-NEXT: rep bsfl %eax, %eax999; X64-NEXT: retq1000 %x = or i32 %xx, 641001 %z = sdiv exact i32 %x, %y1002 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)1003 ret i32 %r1004}1005 1006define i32 @sdiv_maybe_zero(i32 %x, i32 %y) {1007; X86-LABEL: sdiv_maybe_zero:1008; X86: # %bb.0:1009; X86-NEXT: movl {{[0-9]+}}(%esp), %eax1010; X86-NEXT: cltd1011; X86-NEXT: idivl {{[0-9]+}}(%esp)1012; X86-NEXT: bsfl %eax, %ecx1013; X86-NEXT: movl $32, %eax1014; X86-NEXT: cmovnel %ecx, %eax1015; X86-NEXT: retl1016;1017; X64-LABEL: sdiv_maybe_zero:1018; X64: # %bb.0:1019; X64-NEXT: movl %edi, %eax1020; X64-NEXT: cltd1021; X64-NEXT: idivl %esi1022; X64-NEXT: movl $32, %ecx1023; X64-NEXT: rep bsfl %eax, %ecx1024; X64-NEXT: movl %ecx, %eax1025; X64-NEXT: retq1026 %z = sdiv exact i32 %x, %y1027 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)1028 ret i32 %r1029}1030 1031define i32 @add_known_nonzero(i32 %xx, i32 %y) {1032; X86-LABEL: add_known_nonzero:1033; X86: # %bb.0:1034; X86-NEXT: movl {{[0-9]+}}(%esp), %eax1035; X86-NEXT: orl $1, %eax1036; X86-NEXT: addl {{[0-9]+}}(%esp), %eax1037; X86-NEXT: rep bsfl %eax, %eax1038; X86-NEXT: retl1039;1040; X64-LABEL: add_known_nonzero:1041; X64: # %bb.0:1042; X64-NEXT: orl $1, %edi1043; X64-NEXT: addl %esi, %edi1044; X64-NEXT: rep bsfl %edi, %eax1045; X64-NEXT: retq1046 %x = or i32 %xx, 11047 %z = add nuw i32 %x, %y1048 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)1049 ret i32 %r1050}1051 1052define i32 @add_maybe_zero(i32 %xx, i32 %y) {1053; X86-LABEL: add_maybe_zero:1054; X86: # %bb.0:1055; X86-NEXT: movl {{[0-9]+}}(%esp), %eax1056; X86-NEXT: orl $1, %eax1057; X86-NEXT: addl {{[0-9]+}}(%esp), %eax1058; X86-NEXT: bsfl %eax, %ecx1059; X86-NEXT: movl $32, %eax1060; X86-NEXT: cmovnel %ecx, %eax1061; X86-NEXT: retl1062;1063; X64-LABEL: add_maybe_zero:1064; X64: # %bb.0:1065; X64-NEXT: orl $1, %edi1066; X64-NEXT: addl %esi, %edi1067; X64-NEXT: movl $32, %eax1068; X64-NEXT: rep bsfl %edi, %eax1069; X64-NEXT: retq1070 %x = or i32 %xx, 11071 %z = add nsw i32 %x, %y1072 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)1073 ret i32 %r1074}1075 1076define i32 @sub_known_nonzero_neg_case(i32 %xx) {1077; X86-LABEL: sub_known_nonzero_neg_case:1078; X86: # %bb.0:1079; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx1080; X86-NEXT: movl $256, %eax # imm = 0x1001081; X86-NEXT: shll %cl, %eax1082; X86-NEXT: negl %eax1083; X86-NEXT: rep bsfl %eax, %eax1084; X86-NEXT: retl1085;1086; X64-LABEL: sub_known_nonzero_neg_case:1087; X64: # %bb.0:1088; X64-NEXT: movl %edi, %ecx1089; X64-NEXT: movl $256, %eax # imm = 0x1001090; X64-NEXT: # kill: def $cl killed $cl killed $ecx1091; X64-NEXT: shll %cl, %eax1092; X64-NEXT: negl %eax1093; X64-NEXT: rep bsfl %eax, %eax1094; X64-NEXT: retq1095 %x = shl nuw nsw i32 256, %xx1096 %z = sub i32 0, %x1097 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)1098 ret i32 %r1099}1100 1101define i32 @sub_known_nonzero_ne_case(i32 %xx, i32 %yy) {1102; X86-LABEL: sub_known_nonzero_ne_case:1103; X86: # %bb.0:1104; X86-NEXT: movl {{[0-9]+}}(%esp), %eax1105; X86-NEXT: movl %eax, %ecx1106; X86-NEXT: orl $64, %ecx1107; X86-NEXT: andl $-65, %eax1108; X86-NEXT: subl %ecx, %eax1109; X86-NEXT: rep bsfl %eax, %eax1110; X86-NEXT: retl1111;1112; X64-LABEL: sub_known_nonzero_ne_case:1113; X64: # %bb.0:1114; X64-NEXT: movl %edi, %eax1115; X64-NEXT: orl $64, %eax1116; X64-NEXT: andl $-65, %edi1117; X64-NEXT: subl %eax, %edi1118; X64-NEXT: rep bsfl %edi, %eax1119; X64-NEXT: retq1120 %x = or i32 %xx, 641121 %y = and i32 %xx, -651122 %z = sub i32 %y, %x1123 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)1124 ret i32 %r1125}1126 1127define i32 @sub_maybe_zero(i32 %x) {1128; X86-LABEL: sub_maybe_zero:1129; X86: # %bb.0:1130; X86-NEXT: movl {{[0-9]+}}(%esp), %eax1131; X86-NEXT: movl %eax, %ecx1132; X86-NEXT: orl $64, %ecx1133; X86-NEXT: subl %eax, %ecx1134; X86-NEXT: bsfl %ecx, %ecx1135; X86-NEXT: movl $32, %eax1136; X86-NEXT: cmovnel %ecx, %eax1137; X86-NEXT: retl1138;1139; X64-LABEL: sub_maybe_zero:1140; X64: # %bb.0:1141; X64-NEXT: movl %edi, %ecx1142; X64-NEXT: orl $64, %ecx1143; X64-NEXT: subl %edi, %ecx1144; X64-NEXT: movl $32, %eax1145; X64-NEXT: rep bsfl %ecx, %eax1146; X64-NEXT: retq1147 %y = or i32 %x, 641148 %z = sub i32 %y, %x1149 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)1150 ret i32 %r1151}1152 1153define i32 @sub_maybe_zero2(i32 %x) {1154; X86-LABEL: sub_maybe_zero2:1155; X86: # %bb.0:1156; X86-NEXT: xorl %eax, %eax1157; X86-NEXT: subl {{[0-9]+}}(%esp), %eax1158; X86-NEXT: bsfl %eax, %ecx1159; X86-NEXT: movl $32, %eax1160; X86-NEXT: cmovnel %ecx, %eax1161; X86-NEXT: retl1162;1163; X64-LABEL: sub_maybe_zero2:1164; X64: # %bb.0:1165; X64-NEXT: negl %edi1166; X64-NEXT: movl $32, %eax1167; X64-NEXT: rep bsfl %edi, %eax1168; X64-NEXT: retq1169 %z = sub i32 0, %x1170 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)1171 ret i32 %r1172}1173 1174define i32 @mul_known_nonzero_nsw(i32 %x, i32 %yy) {1175; X86-LABEL: mul_known_nonzero_nsw:1176; X86: # %bb.0:1177; X86-NEXT: movl $256, %eax # imm = 0x1001178; X86-NEXT: orl {{[0-9]+}}(%esp), %eax1179; X86-NEXT: imull {{[0-9]+}}(%esp), %eax1180; X86-NEXT: bsfl %eax, %ecx1181; X86-NEXT: movl $32, %eax1182; X86-NEXT: cmovnel %ecx, %eax1183; X86-NEXT: retl1184;1185; X64-LABEL: mul_known_nonzero_nsw:1186; X64: # %bb.0:1187; X64-NEXT: orl $256, %esi # imm = 0x1001188; X64-NEXT: imull %edi, %esi1189; X64-NEXT: movl $32, %eax1190; X64-NEXT: rep bsfl %esi, %eax1191; X64-NEXT: retq1192 %y = or i32 %yy, 2561193 %z = mul nsw i32 %y, %x1194 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)1195 ret i32 %r1196}1197 1198define i32 @mul_known_nonzero_nuw(i32 %x, i32 %yy) {1199; X86-LABEL: mul_known_nonzero_nuw:1200; X86: # %bb.0:1201; X86-NEXT: movl $256, %eax # imm = 0x1001202; X86-NEXT: orl {{[0-9]+}}(%esp), %eax1203; X86-NEXT: imull {{[0-9]+}}(%esp), %eax1204; X86-NEXT: bsfl %eax, %ecx1205; X86-NEXT: movl $32, %eax1206; X86-NEXT: cmovnel %ecx, %eax1207; X86-NEXT: retl1208;1209; X64-LABEL: mul_known_nonzero_nuw:1210; X64: # %bb.0:1211; X64-NEXT: orl $256, %esi # imm = 0x1001212; X64-NEXT: imull %edi, %esi1213; X64-NEXT: movl $32, %eax1214; X64-NEXT: rep bsfl %esi, %eax1215; X64-NEXT: retq1216 %y = or i32 %yy, 2561217 %z = mul nuw i32 %y, %x1218 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)1219 ret i32 %r1220}1221 1222define i32 @mul_maybe_zero(i32 %x, i32 %y) {1223; X86-LABEL: mul_maybe_zero:1224; X86: # %bb.0:1225; X86-NEXT: movl {{[0-9]+}}(%esp), %eax1226; X86-NEXT: imull {{[0-9]+}}(%esp), %eax1227; X86-NEXT: bsfl %eax, %ecx1228; X86-NEXT: movl $32, %eax1229; X86-NEXT: cmovnel %ecx, %eax1230; X86-NEXT: retl1231;1232; X64-LABEL: mul_maybe_zero:1233; X64: # %bb.0:1234; X64-NEXT: imull %esi, %edi1235; X64-NEXT: movl $32, %eax1236; X64-NEXT: rep bsfl %edi, %eax1237; X64-NEXT: retq1238 %z = mul nuw nsw i32 %y, %x1239 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)1240 ret i32 %r1241}1242 1243define i32 @bitcast_known_nonzero(<2 x i16> %xx) {1244; X86-LABEL: bitcast_known_nonzero:1245; X86: # %bb.0:1246; X86-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]1247; X86-NEXT: pslld $23, %xmm01248; X86-NEXT: paddd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm01249; X86-NEXT: cvttps2dq %xmm0, %xmm01250; X86-NEXT: pshuflw {{.*#+}} xmm0 = xmm0[0,2,2,3,4,5,6,7]1251; X86-NEXT: pmullw {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0 # [256,256,u,u,u,u,u,u]1252; X86-NEXT: movd %xmm0, %eax1253; X86-NEXT: bsfl %eax, %ecx1254; X86-NEXT: movl $32, %eax1255; X86-NEXT: cmovnel %ecx, %eax1256; X86-NEXT: retl1257;1258; X64-LABEL: bitcast_known_nonzero:1259; X64: # %bb.0:1260; X64-NEXT: vpmovzxwd {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero1261; X64-NEXT: vpslld $23, %xmm0, %xmm01262; X64-NEXT: vpaddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm01263; X64-NEXT: vcvttps2dq %xmm0, %xmm01264; X64-NEXT: vpackusdw %xmm0, %xmm0, %xmm01265; X64-NEXT: vpmullw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [256,256,u,u,u,u,u,u]1266; X64-NEXT: vmovd %xmm0, %ecx1267; X64-NEXT: movl $32, %eax1268; X64-NEXT: rep bsfl %ecx, %eax1269; X64-NEXT: retq1270 %x = shl nuw nsw <2 x i16> <i16 256, i16 256>, %xx1271 %z = bitcast <2 x i16> %x to i321272 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)1273 ret i32 %r1274}1275 1276define i32 @bitcast_maybe_zero(<2 x i16> %x) {1277; X86-LABEL: bitcast_maybe_zero:1278; X86: # %bb.0:1279; X86-NEXT: movd %xmm0, %eax1280; X86-NEXT: bsfl %eax, %ecx1281; X86-NEXT: movl $32, %eax1282; X86-NEXT: cmovnel %ecx, %eax1283; X86-NEXT: retl1284;1285; X64-LABEL: bitcast_maybe_zero:1286; X64: # %bb.0:1287; X64-NEXT: vmovd %xmm0, %ecx1288; X64-NEXT: movl $32, %eax1289; X64-NEXT: rep bsfl %ecx, %eax1290; X64-NEXT: retq1291 %z = bitcast <2 x i16> %x to i321292 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)1293 ret i32 %r1294}1295 1296define i32 @bitcast_from_float(float %x) {1297; X86-LABEL: bitcast_from_float:1298; X86: # %bb.0:1299; X86-NEXT: bsfl {{[0-9]+}}(%esp), %ecx1300; X86-NEXT: movl $32, %eax1301; X86-NEXT: cmovnel %ecx, %eax1302; X86-NEXT: retl1303;1304; X64-LABEL: bitcast_from_float:1305; X64: # %bb.0:1306; X64-NEXT: vmovd %xmm0, %ecx1307; X64-NEXT: movl $32, %eax1308; X64-NEXT: rep bsfl %ecx, %eax1309; X64-NEXT: retq1310 %z = bitcast float %x to i321311 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)1312 ret i32 %r1313}1314 1315define i32 @zext_known_nonzero(i16 %xx) {1316; X86-LABEL: zext_known_nonzero:1317; X86: # %bb.0:1318; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx1319; X86-NEXT: movl $256, %eax # imm = 0x1001320; X86-NEXT: shll %cl, %eax1321; X86-NEXT: movzwl %ax, %eax1322; X86-NEXT: rep bsfl %eax, %eax1323; X86-NEXT: retl1324;1325; X64-LABEL: zext_known_nonzero:1326; X64: # %bb.0:1327; X64-NEXT: movl %edi, %ecx1328; X64-NEXT: movl $256, %eax # imm = 0x1001329; X64-NEXT: # kill: def $cl killed $cl killed $ecx1330; X64-NEXT: shll %cl, %eax1331; X64-NEXT: movzwl %ax, %eax1332; X64-NEXT: rep bsfl %eax, %eax1333; X64-NEXT: retq1334 %x = shl nuw nsw i16 256, %xx1335 %z = zext i16 %x to i321336 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)1337 ret i32 %r1338}1339 1340define i32 @zext_maybe_zero(i16 %x) {1341; X86-LABEL: zext_maybe_zero:1342; X86: # %bb.0:1343; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax1344; X86-NEXT: bsfl %eax, %ecx1345; X86-NEXT: movl $32, %eax1346; X86-NEXT: cmovnel %ecx, %eax1347; X86-NEXT: retl1348;1349; X64-LABEL: zext_maybe_zero:1350; X64: # %bb.0:1351; X64-NEXT: movzwl %di, %ecx1352; X64-NEXT: movl $32, %eax1353; X64-NEXT: rep bsfl %ecx, %eax1354; X64-NEXT: retq1355 %z = zext i16 %x to i321356 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)1357 ret i32 %r1358}1359 1360define i32 @sext_known_nonzero(i16 %xx) {1361; X86-LABEL: sext_known_nonzero:1362; X86: # %bb.0:1363; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx1364; X86-NEXT: movl $256, %eax # imm = 0x1001365; X86-NEXT: shll %cl, %eax1366; X86-NEXT: movzwl %ax, %eax1367; X86-NEXT: rep bsfl %eax, %eax1368; X86-NEXT: retl1369;1370; X64-LABEL: sext_known_nonzero:1371; X64: # %bb.0:1372; X64-NEXT: movl %edi, %ecx1373; X64-NEXT: movl $256, %eax # imm = 0x1001374; X64-NEXT: # kill: def $cl killed $cl killed $ecx1375; X64-NEXT: shll %cl, %eax1376; X64-NEXT: movzwl %ax, %eax1377; X64-NEXT: rep bsfl %eax, %eax1378; X64-NEXT: retq1379 %x = shl nuw nsw i16 256, %xx1380 %z = sext i16 %x to i321381 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)1382 ret i32 %r1383}1384 1385define i32 @sext_maybe_zero(i16 %x) {1386; X86-LABEL: sext_maybe_zero:1387; X86: # %bb.0:1388; X86-NEXT: movswl {{[0-9]+}}(%esp), %eax1389; X86-NEXT: bsfl %eax, %ecx1390; X86-NEXT: movl $32, %eax1391; X86-NEXT: cmovnel %ecx, %eax1392; X86-NEXT: retl1393;1394; X64-LABEL: sext_maybe_zero:1395; X64: # %bb.0:1396; X64-NEXT: movswl %di, %ecx1397; X64-NEXT: movl $32, %eax1398; X64-NEXT: rep bsfl %ecx, %eax1399; X64-NEXT: retq1400 %z = sext i16 %x to i321401 %r = call i32 @llvm.cttz.i32(i32 %z, i1 false)1402 ret i32 %r1403}1404