[PATCH] D12136: [X86] Emit more efficient >= comparisons against 0

David Majnemer via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 18 23:29:32 PDT 2015


majnemer created this revision.
majnemer added reviewers: chandlerc, resistor.
majnemer added a subscriber: llvm-commits.

We don't do a great job with >= 0 comparisons against zero when the
result is used as an i8.

Given something like:
void f(long long LL, bool *B) {
  *B = LL >= 0;
}

We used to generate:
  shrq    $63, %rdi
  xorb    $1, %dil
  movb    %dil, (%rsi)

Now we generate:
  testq   %rdi, %rdi
  setns   (%rsi)

http://reviews.llvm.org/D12136

Files:
  lib/Target/X86/X86ISelLowering.cpp
  test/CodeGen/X86/cmp.ll

Index: test/CodeGen/X86/cmp.ll
===================================================================
--- test/CodeGen/X86/cmp.ll
+++ test/CodeGen/X86/cmp.ll
@@ -211,3 +211,14 @@
 ; CHECK:  shrl	$16, %edi
 ; CHECK:  cmpl	%esi, %edi
 }
+
+define i8 @test16(i8* %B, i32 %L) {
+  %lshr  = lshr i32 %L, 31
+  %trunc = trunc i32 %lshr to i8
+  %not   = xor i8 %trunc, 1
+  ret i8 %not
+
+; CHECK-LABEL: test16:
+; CHECK:  testl   %esi, %esi
+; CHECK:  setns   %al
+}
Index: lib/Target/X86/X86ISelLowering.cpp
===================================================================
--- lib/Target/X86/X86ISelLowering.cpp
+++ lib/Target/X86/X86ISelLowering.cpp
@@ -24074,13 +24074,56 @@
   return SDValue();
 }
 
+static SDValue foldXorTruncShiftIntoCmp(SDNode *N, SelectionDAG &DAG) {
+  // This is only worth doing if the output type is i8.
+  if (N->getValueType(0) != MVT::i8)
+    return SDValue();
+
+  SDValue N0 = N->getOperand(0);
+  SDValue N1 = N->getOperand(1);
+
+  // We should be performing an xor aginst a truncated shift.
+  if (N0.getOpcode() != ISD::TRUNCATE)
+    return SDValue();
+
+  // Make sure we are performing an xor against one.
+  if (!isa<ConstantSDNode>(N1) || !cast<ConstantSDNode>(N1)->isOne())
+    return SDValue();
+
+  // SetCC on x86 zero extends so only act on this if it's a logical shift.
+  SDValue Shift = N0.getOperand(0);
+  if (Shift.getOpcode() != ISD::SRL)
+    return SDValue();
+
+  // Make sure we are truncating from one of i16, i32 or i64.
+  EVT ShiftTy = Shift.getValueType();
+  if (ShiftTy != MVT::i16 && ShiftTy != MVT::i32 && ShiftTy != MVT::i64)
+    return SDValue();
+
+  // Make sure the shift ammount extracts the sign bit.
+  if (!isa<ConstantSDNode>(Shift.getOperand(1)) ||
+      Shift.getConstantOperandVal(1) != ShiftTy.getSizeInBits() - 1)
+    return SDValue();
+
+  // Create a greater-than comparison against -1.
+  SDLoc DL(N);
+  SDValue ShiftOp = Shift.getOperand(0);
+  EVT ShiftOpTy = ShiftOp.getValueType();
+  SDValue Cond = DAG.getSetCC(DL, MVT::i8, ShiftOp,
+                              DAG.getConstant(-1, DL, ShiftOpTy), ISD::SETGT);
+  return Cond;
+}
+
 // PerformXorCombine - Attempts to turn XOR nodes into BLSMSK nodes
 static SDValue PerformXorCombine(SDNode *N, SelectionDAG &DAG,
                                  TargetLowering::DAGCombinerInfo &DCI,
                                  const X86Subtarget *Subtarget) {
   if (DCI.isBeforeLegalizeOps())
     return SDValue();
 
+  if (SDValue RV = foldXorTruncShiftIntoCmp(N, DAG))
+    return RV;
+
   if (Subtarget->hasCMov())
     if (SDValue RV = performIntegerAbsCombine(N, DAG))
       return RV;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D12136.32504.patch
Type: text/x-patch
Size: 2634 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150819/deba69aa/attachment.bin>


More information about the llvm-commits mailing list