This is also causing <a href="http://llvm.org/PR13577">http://llvm.org/PR13577</a><div><br></div><div>I may revert this as I think we've got pretty good reproduction steps now.</div><div class="gmail_extra"><br><br><div class="gmail_quote">
On Fri, Aug 10, 2012 at 7:15 PM, David Dean <span dir="ltr"><<a href="mailto:david_dean@apple.com" target="_blank">david_dean@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This is breaking some of the dejagnu tests:<br>
<br>
gcc.c-torture/execute/ieee/copysign1.c compilation,  -O0<br>
gcc.c-torture/execute/ieee/copysign1.c compilation,  -O1<br>
gcc.c-torture/execute/ieee/copysign1.c compilation,  -O2<br>
gcc.c-torture/execute/ieee/copysign1.c compilation,  -O3 -fomit-frame-pointer<br>
gcc.c-torture/execute/ieee/copysign1.c compilation,  -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions<br>
gcc.c-torture/execute/ieee/copysign1.c compilation,  -O3 -fomit-frame-pointer -funroll-loops<br>
gcc.c-torture/execute/ieee/copysign1.c compilation,  -O3 -g<br>
gcc.c-torture/execute/ieee/copysign1.c compilation,  -Os<br>
gcc.c-torture/execute/ieee/copysign2.c compilation,  -O0<br>
<br>
You can reproduce it with:<br>
<br>
clang gcc.c-torture/execute/ieee/copysign1.c -w -fnested-functions -O0 -ffloat-store -fno-show-column -Wl,-multiply_defined,suppress -lm -o copysign1.x0<br>
<br>
The result is:<br>
fatal error: error in backend: Cannot select: 0x10213c310: f80,glue = X86ISD::CMOV 0x10213c510, 0x10213c610, 0x10213c810, 0x102137310 [ID=25]<br>
  0x10213c510: f80 = fabs 0x10213bf10 [ID=22]<br>
    0x10213bf10: f80,ch = load 0x102137010, 0x10213bb10, 0x10213ba10<LD10[%x.addr](align=16)> [ORD=7] [ID=20]<br>
      0x10213bb10: i64 = FrameIndex<0> [ORD=5] [ID=2]<br>
      0x10213ba10: i64 = undef [ORD=5] [ID=3]<br>
  0x10213c610: f80 = fneg 0x10213c510 [ID=24]<br>
    0x10213c510: f80 = fabs 0x10213bf10 [ID=22]<br>
      0x10213bf10: f80,ch = load 0x102137010, 0x10213bb10, 0x10213ba10<LD10[%x.addr](align=16)> [ORD=7] [ID=20]<br>
        0x10213bb10: i64 = FrameIndex<0> [ORD=5] [ID=2]<br>
        0x10213ba10: i64 = undef [ORD=5] [ID=3]<br>
  0x10213c810: i8 = Constant<15> [ID=12]<br>
  0x102137310: i32 = X86ISD::CMP 0x10213c110, 0x10213c210 [ID=23]<br>
    0x10213c110: i64 = shl 0x102137510, 0x10213c010 [ID=21]<br>
      0x102137510: i64,ch = load 0x102136e10, 0x102143310, 0x10213ba10<LD8[FixedStack2+8]> [ID=19]<br>
        0x102143310: i64 = or 0x102137710, 0x10213bc10 [ID=15]<br>
          0x102137710: i64 = FrameIndex<2> [ID=8]<br>
          0x10213bc10: i64 = Constant<8> [ID=9]<br>
        0x10213ba10: i64 = undef [ORD=5] [ID=3]<br>
      0x10213c010: i8 = Constant<48> [ID=10]<br>
    0x10213c210: i64 = Constant<0> [ID=11]<br>
In function: cl<br>
compiler exited with status 1<br>
<div class="HOEnZb"><div class="h5"><br>
On 10 Aug 2012, at 12:58 PM, Michael Liao <<a href="mailto:michael.liao@intel.com">michael.liao@intel.com</a>> wrote:<br>
<br>
> Author: hliao<br>
> Date: Fri Aug 10 14:58:13 2012<br>
> New Revision: 161687<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=161687&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=161687&view=rev</a><br>
> Log:<br>
> add X86-specific DAG optimization to simplify boolean test<br>
><br>
> - if a boolean test (X86ISD::CMP or X86ISD:SUB) checks a boolean value<br>
>  generated from X86ISD::SETCC, try to simplify the boolean value<br>
>  generation and checking by reusing the original EFLAGS with proper<br>
>  condition code<br>
> - add hooks to X86 specific SETCC/BRCOND/CMOV, the major 3 places<br>
>  consuming EFLAGS<br>
><br>
> part of patches fixing PR12312<br>
><br>
><br>
> Added:<br>
>    llvm/trunk/test/CodeGen/X86/bool-simplify.ll<br>
> Modified:<br>
>    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
><br>
> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=161687&r1=161686&r2=161687&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=161687&r1=161686&r2=161687&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)<br>
> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Aug 10 14:58:13 2012<br>
> @@ -13782,6 +13782,72 @@<br>
>   return SDValue();<br>
> }<br>
><br>
> +// Check whether a boolean test is testing a boolean value generated by<br>
> +// X86ISD::SETCC. If so, return the operand of that SETCC and proper condition<br>
> +// code.<br>
> +//<br>
> +// Simplify the following patterns:<br>
> +// (Op (CMP (SETCC Cond EFLAGS) 1) EQ) or<br>
> +// (Op (CMP (SETCC Cond EFLAGS) 0) NEQ)<br>
> +// to (Op EFLAGS Cond)<br>
> +//<br>
> +// (Op (CMP (SETCC Cond EFLAGS) 0) EQ) or<br>
> +// (Op (CMP (SETCC Cond EFLAGS) 1) NEQ)<br>
> +// to (Op EFLAGS !Cond)<br>
> +//<br>
> +// where Op could be BRCOND or CMOV.<br>
> +//<br>
> +static SDValue BoolTestSetCCCombine(SDValue Cmp, X86::CondCode &CC) {<br>
> +  // Quit if not CMP and SUB with its value result used.<br>
> +  if (Cmp.getOpcode() != X86ISD::CMP &&<br>
> +      (Cmp.getOpcode() != X86ISD::SUB || Cmp.getNode()->hasAnyUseOfValue(0)))<br>
> +      return SDValue();<br>
> +<br>
> +  // Quit if not used as a boolean value.<br>
> +  if (CC != X86::COND_E && CC != X86::COND_NE)<br>
> +    return SDValue();<br>
> +<br>
> +  // Check CMP operands. One of them should be 0 or 1 and the other should be<br>
> +  // an SetCC or extended from it.<br>
> +  SDValue Op1 = Cmp.getOperand(0);<br>
> +  SDValue Op2 = Cmp.getOperand(1);<br>
> +<br>
> +  SDValue SetCC;<br>
> +  const ConstantSDNode* C = 0;<br>
> +  bool needOppositeCond = (CC == X86::COND_E);<br>
> +<br>
> +  if ((C = dyn_cast<ConstantSDNode>(Op1)))<br>
> +    SetCC = Op2;<br>
> +  else if ((C = dyn_cast<ConstantSDNode>(Op2)))<br>
> +    SetCC = Op1;<br>
> +  else // Quit if all operands are not constants.<br>
> +    return SDValue();<br>
> +<br>
> +  if (C->getZExtValue() == 1)<br>
> +    needOppositeCond = !needOppositeCond;<br>
> +  else if (C->getZExtValue() != 0)<br>
> +    // Quit if the constant is neither 0 or 1.<br>
> +    return SDValue();<br>
> +<br>
> +  // Skip 'zext' node.<br>
> +  if (SetCC.getOpcode() == ISD::ZERO_EXTEND)<br>
> +    SetCC = SetCC.getOperand(0);<br>
> +<br>
> +  // Quit if not SETCC.<br>
> +  // FIXME: So far we only handle the boolean value generated from SETCC. If<br>
> +  // there is other ways to generate boolean values, we need handle them here<br>
> +  // as well.<br>
> +  if (SetCC.getOpcode() != X86ISD::SETCC)<br>
> +    return SDValue();<br>
> +<br>
> +  // Set the condition code or opposite one if necessary.<br>
> +  CC = X86::CondCode(SetCC.getConstantOperandVal(0));<br>
> +  if (needOppositeCond)<br>
> +    CC = X86::GetOppositeBranchCondition(CC);<br>
> +<br>
> +  return SetCC.getOperand(1);<br>
> +}<br>
> +<br>
> /// Optimize X86ISD::CMOV [LHS, RHS, CONDCODE (e.g. X86::COND_NE), CONDVAL]<br>
> static SDValue PerformCMOVCombine(SDNode *N, SelectionDAG &DAG,<br>
>                                   TargetLowering::DAGCombinerInfo &DCI) {<br>
> @@ -13795,6 +13861,7 @@<br>
>   SDValue TrueOp = N->getOperand(1);<br>
>   X86::CondCode CC = (X86::CondCode)N->getConstantOperandVal(2);<br>
>   SDValue Cond = N->getOperand(3);<br>
> +<br>
>   if (CC == X86::COND_E || CC == X86::COND_NE) {<br>
>     switch (Cond.getOpcode()) {<br>
>     default: break;<br>
> @@ -13806,6 +13873,16 @@<br>
>     }<br>
>   }<br>
><br>
> +  SDValue Flags;<br>
> +<br>
> +  Flags = BoolTestSetCCCombine(Cond, CC);<br>
> +  if (Flags.getNode()) {<br>
> +    SDValue Ops[] = { FalseOp, TrueOp,<br>
> +                      DAG.getConstant(CC, MVT::i8), Flags };<br>
> +    return DAG.getNode(X86ISD::CMOV, DL, N->getVTList(),<br>
> +                       Ops, array_lengthof(Ops));<br>
> +  }<br>
> +<br>
>   // If this is a select between two integer constants, try to do some<br>
>   // optimizations.  Note that the operands are ordered the opposite of SELECT<br>
>   // operands.<br>
> @@ -15285,19 +15362,50 @@<br>
><br>
> // Optimize  RES = X86ISD::SETCC CONDCODE, EFLAG_INPUT<br>
> static SDValue PerformSETCCCombine(SDNode *N, SelectionDAG &DAG) {<br>
> -  unsigned X86CC = N->getConstantOperandVal(0);<br>
> -  SDValue EFLAG = N->getOperand(1);<br>
>   DebugLoc DL = N->getDebugLoc();<br>
> +  X86::CondCode CC = X86::CondCode(N->getConstantOperandVal(0));<br>
> +  SDValue EFLAGS = N->getOperand(1);<br>
><br>
>   // Materialize "setb reg" as "sbb reg,reg", since it can be extended without<br>
>   // a zext and produces an all-ones bit which is more useful than 0/1 in some<br>
>   // cases.<br>
> -  if (X86CC == X86::COND_B)<br>
> +  if (CC == X86::COND_B)<br>
>     return DAG.getNode(ISD::AND, DL, MVT::i8,<br>
>                        DAG.getNode(X86ISD::SETCC_CARRY, DL, MVT::i8,<br>
> -                                   DAG.getConstant(X86CC, MVT::i8), EFLAG),<br>
> +                                   DAG.getConstant(CC, MVT::i8), EFLAGS),<br>
>                        DAG.getConstant(1, MVT::i8));<br>
><br>
> +  SDValue Flags;<br>
> +<br>
> +  Flags = BoolTestSetCCCombine(EFLAGS, CC);<br>
> +  if (Flags.getNode()) {<br>
> +    SDValue Cond = DAG.getConstant(CC, MVT::i8);<br>
> +    return DAG.getNode(X86ISD::SETCC, DL, N->getVTList(), Cond, Flags);<br>
> +  }<br>
> +<br>
> +  return SDValue();<br>
> +}<br>
> +<br>
> +// Optimize branch condition evaluation.<br>
> +//<br>
> +static SDValue PerformBrCondCombine(SDNode *N, SelectionDAG &DAG,<br>
> +                                    TargetLowering::DAGCombinerInfo &DCI,<br>
> +                                    const X86Subtarget *Subtarget) {<br>
> +  DebugLoc DL = N->getDebugLoc();<br>
> +  SDValue Chain = N->getOperand(0);<br>
> +  SDValue Dest = N->getOperand(1);<br>
> +  SDValue EFLAGS = N->getOperand(3);<br>
> +  X86::CondCode CC = X86::CondCode(N->getConstantOperandVal(2));<br>
> +<br>
> +  SDValue Flags;<br>
> +<br>
> +  Flags = BoolTestSetCCCombine(EFLAGS, CC);<br>
> +  if (Flags.getNode()) {<br>
> +    SDValue Cond = DAG.getConstant(CC, MVT::i8);<br>
> +    return DAG.getNode(X86ISD::BRCOND, DL, N->getVTList(), Chain, Dest, Cond,<br>
> +                       Flags);<br>
> +  }<br>
> +<br>
>   return SDValue();<br>
> }<br>
><br>
> @@ -15515,6 +15623,7 @@<br>
>   case ISD::TRUNCATE:       return PerformTruncateCombine(N, DAG, DCI);<br>
>   case ISD::SETCC:          return PerformISDSETCCCombine(N, DAG);<br>
>   case X86ISD::SETCC:       return PerformSETCCCombine(N, DAG);<br>
> +  case X86ISD::BRCOND:      return PerformBrCondCombine(N, DAG, DCI, Subtarget);<br>
>   case X86ISD::SHUFP:       // Handle all target specific shuffles<br>
>   case X86ISD::PALIGN:<br>
>   case X86ISD::UNPCKH:<br>
><br>
> Added: llvm/trunk/test/CodeGen/X86/bool-simplify.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/bool-simplify.ll?rev=161687&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/bool-simplify.ll?rev=161687&view=auto</a><br>

> ==============================================================================<br>
> --- llvm/trunk/test/CodeGen/X86/bool-simplify.ll (added)<br>
> +++ llvm/trunk/test/CodeGen/X86/bool-simplify.ll Fri Aug 10 14:58:13 2012<br>
> @@ -0,0 +1,42 @@<br>
> +; RUN: llc < %s -march=x86-64 -mattr=+sse41,-avx | FileCheck %s<br>
> +<br>
> +define i32 @foo(<2 x i64> %c, i32 %a, i32 %b) {<br>
> +  %t1 = call i32 @llvm.x86.sse41.ptestz(<2 x i64> %c, <2 x i64> %c)<br>
> +  %t2 = icmp ne i32 %t1, 0<br>
> +  %t3 = select i1 %t2, i32 %a, i32 %b<br>
> +  ret i32 %t3<br>
> +; CHECK: foo<br>
> +; CHECK: ptest<br>
> +; CHECK-NOT: testl<br>
> +; CHECK: cmov<br>
> +; CHECK: ret<br>
> +}<br>
> +<br>
> +define i32 @bar(<2 x i64> %c) {<br>
> +entry:<br>
> +  %0 = call i32 @llvm.x86.sse41.ptestz(<2 x i64> %c, <2 x i64> %c)<br>
> +  %1 = icmp ne i32 %0, 0<br>
> +  br i1 %1, label %if-true-block, label %endif-block<br>
> +if-true-block:                                    ; preds = %entry<br>
> +  ret i32 0<br>
> +endif-block:                                      ; preds = %entry,<br>
> +  ret i32 1<br>
> +; CHECK: bar<br>
> +; CHECK: ptest<br>
> +; CHECK-NOT: testl<br>
> +; CHECK: jne<br>
> +; CHECK: ret<br>
> +}<br>
> +<br>
> +define i32 @bax(<2 x i64> %c) {<br>
> +  %t1 = call i32 @llvm.x86.sse41.ptestz(<2 x i64> %c, <2 x i64> %c)<br>
> +  %t2 = icmp eq i32 %t1, 1<br>
> +  %t3 = zext i1 %t2 to i32<br>
> +  ret i32 %t3<br>
> +; CHECK: bax<br>
> +; CHECK: ptest<br>
> +; CHECK-NOT: cmpl<br>
> +; CHECK: ret<br>
> +}<br>
> +<br>
> +declare i32 @llvm.x86.sse41.ptestz(<2 x i64>, <2 x i64>) nounwind readnone<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
<br>
</div></div><span class="HOEnZb"><font color="#888888">-David<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</div></div></blockquote></div><br></div>