From: Peter Collingbourne Date: Fri, 21 Oct 2016 19:57:55 +0000 (+0000) Subject: X86: Improve BT instruction selection for 64-bit values. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7d77c5caa7216c96c68a6c4f1042b1b5c01e1ae2;p=llvm X86: Improve BT instruction selection for 64-bit values. If a 64-bit value is tested against a bit which is known to be in the range [0..31) (modulo 64), we can use the 32-bit BT instruction, which has a slightly shorter encoding. Differential Revision: https://reviews.llvm.org/D25862 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@284864 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 28397d8648d..665ab04b6c6 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -15314,6 +15314,14 @@ static SDValue getBitTestCondition(SDValue Src, SDValue BitNo, ISD::CondCode CC, if (Src.getValueType() == MVT::i8 || Src.getValueType() == MVT::i16) Src = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, Src); + // See if we can use the 32-bit instruction instead of the 64-bit one for a + // shorter encoding. Since the former takes the modulo 32 of BitNo and the + // latter takes the modulo 64, this is only valid if the 5th bit of BitNo is + // known to be zero. + if (Src.getValueType() == MVT::i64 && + DAG.MaskedValueIsZero(BitNo, APInt(BitNo.getValueSizeInBits(), 32))) + Src = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Src); + // If the operand types disagree, extend the shift amount to match. Since // BT ignores high bits (like shifts) we can use anyextend. if (Src.getValueType() != BitNo.getValueType()) diff --git a/test/CodeGen/X86/bt.ll b/test/CodeGen/X86/bt.ll index a6705088745..6576f33a5b9 100644 --- a/test/CodeGen/X86/bt.ll +++ b/test/CodeGen/X86/bt.ll @@ -596,3 +596,15 @@ define zeroext i1 @invert(i32 %flags, i32 %flag) nounwind { ret i1 %tobool } +define zeroext i1 @extend(i32 %bit, i64 %bits) { +; CHECK-LABEL: extend: +; CHECK: # BB#0: +; CHECK-NEXT: btl %edi, %esi +entry: + %and = and i32 %bit, 31 + %sh_prom = zext i32 %and to i64 + %shl = shl i64 1, %sh_prom + %and1 = and i64 %shl, %bits + %tobool = icmp ne i64 %and1, 0 + ret i1 %tobool +}