diff options
author | Evan Cheng <evan.cheng@apple.com> | 2006-01-13 01:03:02 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2006-01-13 01:03:02 +0000 |
commit | 1bcee3602e8017ebe255b30800a43d62f16edffd (patch) | |
tree | e826762bef6d5657337fd7001e3608d20eb87473 | |
parent | 2085a9d99b5ab479b9bbbf0d07e94961cd676ac7 (diff) | |
download | external_llvm-1bcee3602e8017ebe255b30800a43d62f16edffd.zip external_llvm-1bcee3602e8017ebe255b30800a43d62f16edffd.tar.gz external_llvm-1bcee3602e8017ebe255b30800a43d62f16edffd.tar.bz2 |
Fix a SETCC / BRCOND folding bug.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25259 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 4849c95..9742ccb 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -1572,14 +1572,24 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { bool isFP = MVT::isFloatingPoint(VT); bool isFPStack = isFP && (X86Vector < SSE2); bool isFPSSE = isFP && (X86Vector >= SSE2); - bool isValid = false; + bool addTest = false; SDOperand Op0 = Op.getOperand(0); SDOperand Cond, CC; if (Op0.getOpcode() == X86ISD::SETCC) { - CC = Op0.getOperand(0); - Cond = Op0.getOperand(1); - isValid = - !(isFPStack && !hasFPCMov(cast<ConstantSDNode>(CC)->getSignExtended())); + // If condition flag is set by a X86ISD::CMP, then make a copy of it + // (since flag operand cannot be shared). If the X86ISD::SETCC does not + // have another use it will be eliminated. + // If the X86ISD::SETCC has more than one use, then it's probably better + // to use a test instead of duplicating the X86ISD::CMP (for register + // pressure reason). + if (Cond.hasOneUse() && Cond.getOperand(1).getOpcode() == X86ISD::CMP) { + CC = Op0.getOperand(0); + Cond = Op0.getOperand(1); + addTest = + !(isFPStack && + !hasFPCMov(cast<ConstantSDNode>(CC)->getSignExtended())); + } else + addTest = true; } else if (Op0.getOpcode() == ISD::SETCC) { CC = Op0.getOperand(2); bool isFP = MVT::isFloatingPoint(Op0.getOperand(1).getValueType()); @@ -1587,10 +1597,11 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { CC = DAG.getConstant(X86CC, MVT::i8); Cond = DAG.getNode(X86ISD::CMP, MVT::Flag, Op0.getOperand(0), Op0.getOperand(1)); - isValid = true; - } + addTest = true; + } else + addTest = true; - if (!isValid) { + if (!addTest) { CC = DAG.getConstant(X86ISD::COND_E, MVT::i8); Cond = DAG.getNode(X86ISD::TEST, MVT::Flag, Op0, Op0); } @@ -1606,13 +1617,24 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { return DAG.getNode(X86ISD::CMOV, Tys, Ops); } case ISD::BRCOND: { + bool addTest = false; SDOperand Cond = Op.getOperand(1); SDOperand Dest = Op.getOperand(2); SDOperand CC; - // TODO: handle Cond == OR / AND / XOR if (Cond.getOpcode() == X86ISD::SETCC) { - CC = Cond.getOperand(0); - Cond = Cond.getOperand(1); + // If condition flag is set by a X86ISD::CMP, then make a copy of it + // (since flag operand cannot be shared). If the X86ISD::SETCC does not + // have another use it will be eliminated. + // If the X86ISD::SETCC has more than one use, then it's probably better + // to use a test instead of duplicating the X86ISD::CMP (for register + // pressure reason). + if (Cond.hasOneUse() && Cond.getOperand(1).getOpcode() == X86ISD::CMP) { + CC = Cond.getOperand(0); + Cond = DAG.getNode(X86ISD::CMP, MVT::Flag, + Cond.getOperand(1).getOperand(0), + Cond.getOperand(1).getOperand(1)); + } else + addTest = true; } else if (Cond.getOpcode() == ISD::SETCC) { CC = Cond.getOperand(2); bool isFP = MVT::isFloatingPoint(Cond.getOperand(1).getValueType()); @@ -1620,7 +1642,10 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { CC = DAG.getConstant(X86CC, MVT::i8); Cond = DAG.getNode(X86ISD::CMP, MVT::Flag, Cond.getOperand(0), Cond.getOperand(1)); - } else { + } else + addTest = true; + + if (addTest) { CC = DAG.getConstant(X86ISD::COND_NE, MVT::i8); Cond = DAG.getNode(X86ISD::TEST, MVT::Flag, Cond, Cond); } |