diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -364,6 +364,12 @@ // encoding. setOperationPromotedToType(ISD::CTTZ , MVT::i8 , MVT::i32); setOperationPromotedToType(ISD::CTTZ_ZERO_UNDEF, MVT::i8 , MVT::i32); + + // Promote the i16 zero undef variant and force them on up to i32 when tzcnt + // is enabled. + if (Subtarget.hasBMI()) + setOperationPromotedToType(ISD::CTTZ_ZERO_UNDEF, MVT::i16, MVT::i32); + if (!Subtarget.hasBMI()) { setOperationAction(ISD::CTTZ , MVT::i16 , Custom); setOperationAction(ISD::CTTZ , MVT::i32 , Custom); diff --git a/llvm/test/CodeGen/X86/clz.ll b/llvm/test/CodeGen/X86/clz.ll --- a/llvm/test/CodeGen/X86/clz.ll +++ b/llvm/test/CodeGen/X86/clz.ll @@ -56,12 +56,14 @@ ; ; X86-CLZ-LABEL: cttz_i16: ; X86-CLZ: # %bb.0: -; X86-CLZ-NEXT: tzcntw {{[0-9]+}}(%esp), %ax +; X86-CLZ-NEXT: tzcntl {{[0-9]+}}(%esp), %eax +; X86-CLZ-NEXT: # kill: def $ax killed $ax killed $eax ; X86-CLZ-NEXT: retl ; ; X64-CLZ-LABEL: cttz_i16: ; X64-CLZ: # %bb.0: -; X64-CLZ-NEXT: tzcntw %di, %ax +; X64-CLZ-NEXT: tzcntl %edi, %eax +; X64-CLZ-NEXT: # kill: def $ax killed $ax killed $eax ; X64-CLZ-NEXT: retq %tmp = call i16 @llvm.cttz.i16( i16 %x, i1 true ) ret i16 %tmp