From: Evan Cheng Date: Fri, 19 Feb 2010 00:34:39 +0000 (+0000) Subject: Transform (xor (setcc), (setcc)) == / != 1 to X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=97a35fc3a744c905e1aeed8542fae366c7940f95;p=oota-llvm.git Transform (xor (setcc), (setcc)) == / != 1 to (xor (setcc), (setcc)) != / == 1. e.g. On x86_64 %0 = icmp eq i32 %x, 0 %1 = icmp eq i32 %y, 0 %2 = xor i1 %1, %0 br i1 %2, label %bb, label %return => testl %edi, %edi sete %al testl %esi, %esi sete %cl cmpb %al, %cl je LBB1_2 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96640 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 9f9d8b0ffd5..2cb4fc9c3c5 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -1855,9 +1855,19 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1, SDValue Op0 = N0; if (Op0.getOpcode() == ISD::TRUNCATE) Op0 = Op0.getOperand(0); - if (Op0.getOpcode() == ISD::AND && - isa(Op0.getOperand(1)) && - cast(Op0.getOperand(1))->getAPIntValue() == 1) { + + if ((Op0.getOpcode() == ISD::XOR || Op0.getOpcode() == ISD::AND) && + Op0.getOperand(0).getOpcode() == ISD::SETCC && + Op0.getOperand(1).getOpcode() == ISD::SETCC) { + // (and (setcc), (setcc)) == / != 1 -> (setcc) == / != (setcc) + // (xor (setcc), (setcc)) == / != 1 -> (setcc) != / == (setcc) + if (Op0.getOpcode() == ISD::XOR) + Cond = (Cond == ISD::SETEQ) ? ISD::SETNE : ISD::SETEQ; + return DAG.getSetCC(dl, VT, Op0.getOperand(0), Op0.getOperand(1), + Cond); + } else if (Op0.getOpcode() == ISD::AND && + isa(Op0.getOperand(1)) && + cast(Op0.getOperand(1))->getAPIntValue() == 1) { if (Op0.getValueType() != VT) Op0 = DAG.getNode(ISD::AND, dl, VT, DAG.getNode(ISD::TRUNCATE, dl, VT, Op0.getOperand(0)), diff --git a/test/CodeGen/X86/xor-icmp.ll b/test/CodeGen/X86/xor-icmp.ll index a6bdb13ec6b..2d75c5d7620 100644 --- a/test/CodeGen/X86/xor-icmp.ll +++ b/test/CodeGen/X86/xor-icmp.ll @@ -1,5 +1,6 @@ ; RUN: llc < %s -march=x86 | FileCheck %s -check-prefix=X32 ; RUN: llc < %s -march=x86-64 | FileCheck %s -check-prefix=X64 +; rdar://7367229 define i32 @t(i32 %a, i32 %b) nounwind ssp { entry: @@ -34,3 +35,33 @@ bb1: ; preds = %entry declare i32 @foo(...) declare i32 @bar(...) + +define i32 @t2(i32 %x, i32 %y) nounwind ssp { +; X32: t2: +; X32: cmpl +; X32: sete +; X32: cmpl +; X32: sete +; X32-NOT: xor +; X32: je + +; X64: t2: +; X64: testl +; X64: sete +; X64: testl +; X64: sete +; X64-NOT: xor +; X64: je +entry: + %0 = icmp eq i32 %x, 0 ; [#uses=1] + %1 = icmp eq i32 %y, 0 ; [#uses=1] + %2 = xor i1 %1, %0 ; [#uses=1] + br i1 %2, label %bb, label %return + +bb: ; preds = %entry + %3 = tail call i32 (...)* @foo() nounwind ; [#uses=0] + ret i32 undef + +return: ; preds = %entry + ret i32 undef +}