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,8 +364,13 @@ // encoding. setOperationPromotedToType(ISD::CTTZ , MVT::i8 , MVT::i32); setOperationPromotedToType(ISD::CTTZ_ZERO_UNDEF, MVT::i8 , MVT::i32); - if (!Subtarget.hasBMI()) { - setOperationAction(ISD::CTTZ , MVT::i16 , Custom); + + if (Subtarget.hasBMI()) { + // Promote the i16 zero undef variant and force it on up to i32 when tzcnt + // is enabled. + setOperationPromotedToType(ISD::CTTZ_ZERO_UNDEF, MVT::i16, MVT::i32); + } else { + setOperationAction(ISD::CTTZ, MVT::i16, Custom); setOperationAction(ISD::CTTZ , MVT::i32 , Custom); setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i16 , Legal); setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32 , Legal); 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