[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