Revert commits 96556 and 96640, because commit 96556 breaks the
authorDuncan Sands <baldrick@free.fr>
Fri, 19 Feb 2010 11:30:41 +0000 (11:30 +0000)
committerDuncan Sands <baldrick@free.fr>
Fri, 19 Feb 2010 11:30:41 +0000 (11:30 +0000)
dragonegg self-host build.  I reverted 96640 in order to revert
96556 (96640 goes on top of 96556), but it also looks like with
both of them applied the breakage happens even earlier.  The
symptom of the 96556 miscompile is the following crash:

  llvm[3]: Compiling AlphaISelLowering.cpp for Release build
  cc1plus: /home/duncan/tmp/tmp/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:4982: void llvm::SelectionDAG::ReplaceAllUsesWith(llvm::SDNode*, llvm::SDNode*, llvm::SelectionDAG::DAGUpdateListener*): Assertion `(!From->hasAnyUseOfValue(i) || From->getValueType(i) == To->getValueType(i)) && "Cannot use this version of ReplaceAllUsesWith!"' failed.
  Stack dump:
  0. Running pass 'X86 DAG->DAG Instruction Selection' on function '@_ZN4llvm19AlphaTargetLowering14LowerOperationENS_7SDValueERNS_12SelectionDAGE'
  g++: Internal error: Aborted (program cc1plus)

This occurs when building LLVM using LLVM built by LLVM (via
dragonegg).  Probably LLVM has miscompiled itself, though it
may have miscompiled GCC and/or dragonegg itself: at this point
of the self-host build, all of GCC, LLVM and dragonegg were built
using LLVM.  Unfortunately this kind of thing is extremely hard
to debug, and while I did rummage around a bit I didn't find any
smoking guns, aka obviously miscompiled code.

Found by bisection.

r96556 | evancheng | 2010-02-18 03:13:50 +0100 (Thu, 18 Feb 2010) | 5 lines

Some dag combiner goodness:
Transform br (xor (x, y)) -> br (x != y)
Transform br (xor (xor (x,y), 1)) -> br (x == y)
Also normalize (and (X, 1) == / != 1 -> (and (X, 1)) != / == 0 to match to "test on x86" and "tst on arm"

r96640 | evancheng | 2010-02-19 01:34:39 +0100 (Fri, 19 Feb 2010) | 16 lines

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@96672 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/DAGCombiner.cpp
lib/CodeGen/SelectionDAG/TargetLowering.cpp
lib/Target/X86/X86ISelLowering.cpp
test/CodeGen/X86/critical-edge-split.ll
test/CodeGen/X86/ins_subreg_coalesce-3.ll
test/CodeGen/X86/trunc-to-bool.ll
test/CodeGen/X86/xor-icmp.ll

index c5dba39e3f810eee1de7a9949691af6e9f4ac3f7..7da7848930f1381bc243c02dae490984dd792194 100644 (file)
@@ -4655,8 +4655,7 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) {
             DAG.DeleteNode(Trunc);
           }
           // Replace the uses of SRL with SETCC
-          WorkListRemover DeadNodes(*this);
-          DAG.ReplaceAllUsesOfValueWith(N1, SetCC, &DeadNodes);
+          DAG.ReplaceAllUsesOfValueWith(N1, SetCC);
           removeFromWorkList(N1.getNode());
           DAG.DeleteNode(N1.getNode());
           return SDValue(N, 0);   // Return N so it doesn't get rechecked!
@@ -4664,53 +4663,6 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) {
       }
     }
   }
-  
-  // Transform br(xor(x, y)) -> br(x != y)
-  // Transform br(xor(xor(x,y), 1)) -> br (x == y)
-  if (N1.hasOneUse() && N1.getOpcode() == ISD::XOR) {
-    SDNode *TheXor = N1.getNode();
-    SDValue Op0 = TheXor->getOperand(0);
-    SDValue Op1 = TheXor->getOperand(1);
-    if (Op0.getOpcode() == Op1.getOpcode()) {
-      // Avoid missing important xor optimizations.
-      SDValue Tmp = visitXOR(TheXor);
-      if (Tmp.getNode()) {
-        DEBUG(dbgs() << "\nReplacing.8 ";
-              TheXor->dump(&DAG);
-              dbgs() << "\nWith: ";
-              Tmp.getNode()->dump(&DAG);
-              dbgs() << '\n');
-        WorkListRemover DeadNodes(*this);
-        DAG.ReplaceAllUsesOfValueWith(N1, Tmp, &DeadNodes);
-        removeFromWorkList(TheXor);
-        DAG.DeleteNode(TheXor);
-        return DAG.getNode(ISD::BRCOND, N->getDebugLoc(),
-                           MVT::Other, Chain, Tmp, N2);
-      }
-    }
-
-    if (Op0.getOpcode() != ISD::SETCC && Op1.getOpcode() != ISD::SETCC) {
-      bool Equal = false;
-      if (ConstantSDNode *RHSCI = dyn_cast<ConstantSDNode>(Op0))
-        if (RHSCI->getAPIntValue() == 1 && Op0.hasOneUse() &&
-            Op0.getOpcode() == ISD::XOR) {
-          TheXor = Op0.getNode();
-          Equal = true;
-        }
-    
-      SDValue SetCC = DAG.getSetCC(TheXor->getDebugLoc(),
-                                   TLI.getSetCCResultType(N1.getValueType()),
-                                   Op0, Op1,
-                                   Equal ? ISD::SETEQ : ISD::SETNE);
-      // Replace the uses of XOR with SETCC
-      WorkListRemover DeadNodes(*this);
-      DAG.ReplaceAllUsesOfValueWith(N1, SetCC, &DeadNodes);
-      removeFromWorkList(N1.getNode());
-      DAG.DeleteNode(N1.getNode());
-      return DAG.getNode(ISD::BRCOND, N->getDebugLoc(),
-                         MVT::Other, Chain, SetCC, N2);
-    }
-  }
 
   return SDValue();
 }
@@ -5060,7 +5012,7 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) {
       assert(N->getValueType(2) == MVT::Other && "Malformed indexed loads?");
       if (N->hasNUsesOfValue(0, 0) && N->hasNUsesOfValue(0, 1)) {
         SDValue Undef = DAG.getUNDEF(N->getValueType(0));
-        DEBUG(dbgs() << "\nReplacing.7 ";
+        DEBUG(dbgs() << "\nReplacing.6 ";
               N->dump(&DAG);
               dbgs() << "\nWith: ";
               Undef.getNode()->dump(&DAG);
index 2cb4fc9c3c5ff10ee449e7f1cd0cf1a0d19348c6..e88af4f3e02c185a43bb22c3347fabfc401138b7 100644 (file)
@@ -1775,7 +1775,7 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
         break;   // todo, be more careful with signed comparisons
       }
     } else if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG &&
-               (Cond == ISD::SETEQ || Cond == ISD::SETNE)) {
+                (Cond == ISD::SETEQ || Cond == ISD::SETNE)) {
       EVT ExtSrcTy = cast<VTSDNode>(N0.getOperand(1))->getVT();
       unsigned ExtSrcTyBits = ExtSrcTy.getSizeInBits();
       EVT ExtDstTy = N0.getValueType();
@@ -1809,6 +1809,7 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
                           Cond);
     } else if ((N1C->isNullValue() || N1C->getAPIntValue() == 1) &&
                 (Cond == ISD::SETEQ || Cond == ISD::SETNE)) {
+      
       // SETCC (SETCC), [0|1], [EQ|NE]  -> SETCC
       if (N0.getOpcode() == ISD::SETCC) {
         bool TrueWhenTrue = (Cond == ISD::SETEQ) ^ (N1C->getAPIntValue() != 1);
@@ -1821,9 +1822,9 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
                                   N0.getOperand(0).getValueType().isInteger());
         return DAG.getSetCC(dl, VT, N0.getOperand(0), N0.getOperand(1), CC);
       }
-
+      
       if ((N0.getOpcode() == ISD::XOR ||
-           (N0.getOpcode() == ISD::AND && 
+            (N0.getOpcode() == ISD::AND && 
             N0.getOperand(0).getOpcode() == ISD::XOR &&
             N0.getOperand(1) == N0.getOperand(0).getOperand(1))) &&
           isa<ConstantSDNode>(N0.getOperand(1)) &&
@@ -1846,36 +1847,9 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
                               N0.getOperand(0).getOperand(0),
                               N0.getOperand(1));
           }
-
           return DAG.getSetCC(dl, VT, Val, N1,
                               Cond == ISD::SETEQ ? ISD::SETNE : ISD::SETEQ);
         }
-      } else if (N1C->getAPIntValue() == 1) {
-        // If this is (X&1) == / != 1, normalize it to (X&1) != / == 0.
-        SDValue Op0 = N0;
-        if (Op0.getOpcode() == ISD::TRUNCATE)
-          Op0 = Op0.getOperand(0);
-
-        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<ConstantSDNode>(Op0.getOperand(1)) &&
-                cast<ConstantSDNode>(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)),
-                          DAG.getConstant(1, VT));
-          return DAG.getSetCC(dl, VT, Op0,
-                              DAG.getConstant(0, Op0.getValueType()),
-                              Cond == ISD::SETEQ ? ISD::SETNE : ISD::SETEQ);
-        }
       }
     }
     
index 7b203f285ca55ab0c96d559a3f9913de81039779..4c40fe1803e92ef22a45dff38c1c11f19655e55d 100644 (file)
@@ -5874,31 +5874,26 @@ SDValue X86TargetLowering::EmitCmp(SDValue Op0, SDValue Op1, unsigned X86CC,
 
 /// LowerToBT - Result of 'and' is compared against zero. Turn it into a BT node
 /// if it's possible.
-static SDValue LowerToBT(SDValue And, ISD::CondCode CC,
+static SDValue LowerToBT(SDValue Op0, ISD::CondCode CC,
                          DebugLoc dl, SelectionDAG &DAG) {
-  SDValue Op0 = And.getOperand(0);
-  SDValue Op1 = And.getOperand(1);
-  if (Op0.getOpcode() == ISD::TRUNCATE)
-    Op0 = Op0.getOperand(0);
-  if (Op1.getOpcode() == ISD::TRUNCATE)
-    Op1 = Op1.getOperand(0);
-
   SDValue LHS, RHS;
-  if (Op1.getOpcode() == ISD::SHL) {
-    if (ConstantSDNode *And10C = dyn_cast<ConstantSDNode>(Op1.getOperand(0)))
-      if (And10C->getZExtValue() == 1) {
-        LHS = Op0;
-        RHS = Op1.getOperand(1);
+  if (Op0.getOperand(1).getOpcode() == ISD::SHL) {
+    if (ConstantSDNode *Op010C =
+        dyn_cast<ConstantSDNode>(Op0.getOperand(1).getOperand(0)))
+      if (Op010C->getZExtValue() == 1) {
+        LHS = Op0.getOperand(0);
+        RHS = Op0.getOperand(1).getOperand(1);
       }
-  } else if (Op0.getOpcode() == ISD::SHL) {
-    if (ConstantSDNode *And00C = dyn_cast<ConstantSDNode>(Op0.getOperand(0)))
-      if (And00C->getZExtValue() == 1) {
-        LHS = Op1;
-        RHS = Op0.getOperand(1);
+  } else if (Op0.getOperand(0).getOpcode() == ISD::SHL) {
+    if (ConstantSDNode *Op000C =
+        dyn_cast<ConstantSDNode>(Op0.getOperand(0).getOperand(0)))
+      if (Op000C->getZExtValue() == 1) {
+        LHS = Op0.getOperand(1);
+        RHS = Op0.getOperand(0).getOperand(1);
       }
-  } else if (Op1.getOpcode() == ISD::Constant) {
-    ConstantSDNode *AndRHS = cast<ConstantSDNode>(Op1);
-    SDValue AndLHS = Op0;
+  } else if (Op0.getOperand(1).getOpcode() == ISD::Constant) {
+    ConstantSDNode *AndRHS = cast<ConstantSDNode>(Op0.getOperand(1));
+    SDValue AndLHS = Op0.getOperand(0);
     if (AndRHS->getZExtValue() == 1 && AndLHS.getOpcode() == ISD::SRL) {
       LHS = AndLHS.getOperand(0);
       RHS = AndLHS.getOperand(1);
@@ -5948,17 +5943,6 @@ SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
       return NewSetCC;
   }
 
-  // Look for "(setcc) == / != 1" to avoid unncessary setcc.
-  if (Op0.getOpcode() == X86ISD::SETCC &&
-      Op1.getOpcode() == ISD::Constant &&
-      cast<ConstantSDNode>(Op1)->getZExtValue() == 1 &&
-      (CC == ISD::SETEQ || CC == ISD::SETNE)) {
-    X86::CondCode CCode = (X86::CondCode)Op0.getConstantOperandVal(0);
-    CCode = X86::GetOppositeBranchCondition(CCode);
-    return DAG.getNode(X86ISD::SETCC, dl, MVT::i8,
-                       DAG.getConstant(CCode, MVT::i8), Op0.getOperand(1));
-  }
-
   bool isFP = Op.getOperand(1).getValueType().isFloatingPoint();
   unsigned X86CC = TranslateX86CC(CC, isFP, Op0, Op1, DAG);
   if (X86CC == X86::COND_INVALID)
index f29cbf323e376b5d9957c22a02e27ebed0074d29..4fe554de75a027f95f3852d6b7eae0a7dc7d63b7 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mtriple=i386-apple-darwin -stats -info-output-file - | grep asm-printer | grep 29
+; RUN: llc < %s -mtriple=i386-apple-darwin -tailcallopt=false -stats -info-output-file - | grep asm-printer | grep 31
 
        %CC = type { %Register }
        %II = type { %"struct.XX::II::$_74" }
index 8c1c40976605a568d891a180d83e7704b3288c3e..627edc51c18d761a25e981974a48425e422951ee 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=x86-64 | grep mov | count 3
+; RUN: llc < %s -march=x86-64 | grep mov | count 5
 
        %struct.COMPOSITE = type { i8, i16, i16 }
        %struct.FILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 }
index 60620841064f68f6c1b5cb46043cd2a033f1d3d7..bfab1aef901431f2a48b47c65ddd700836e7815d 100644 (file)
@@ -3,14 +3,13 @@
 ; value and as the operand of a branch.
 ; RUN: llc < %s -march=x86 | FileCheck %s
 
-define i1 @test1(i32 %X) zeroext nounwind {
+define i1 @test1(i32 %X) zeroext {
     %Y = trunc i32 %X to i1
     ret i1 %Y
 }
-; CHECK: test1:
 ; CHECK: andl $1, %eax
 
-define i1 @test2(i32 %val, i32 %mask) nounwind {
+define i1 @test2(i32 %val, i32 %mask) {
 entry:
     %shifted = ashr i32 %val, %mask
     %anded = and i32 %shifted, 1
@@ -21,10 +20,9 @@ ret_true:
 ret_false:
     ret i1 false
 }
-; CHECK: test2:
-; CHECK: btl %eax
+; CHECK: testb $1, %al
 
-define i32 @test3(i8* %ptr) nounwind {
+define i32 @test3(i8* %ptr) {
     %val = load i8* %ptr
     %tmp = trunc i8 %val to i1
     br i1 %tmp, label %cond_true, label %cond_false
@@ -33,10 +31,9 @@ cond_true:
 cond_false:
     ret i32 42
 }
-; CHECK: test3:
-; CHECK: testb $1, (%eax)
+; CHECK: testb $1, %al
 
-define i32 @test4(i8* %ptr) nounwind {
+define i32 @test4(i8* %ptr) {
     %tmp = ptrtoint i8* %ptr to i1
     br i1 %tmp, label %cond_true, label %cond_false
 cond_true:
@@ -44,10 +41,9 @@ cond_true:
 cond_false:
     ret i32 42
 }
-; CHECK: test4:
-; CHECK: testb $1, 4(%esp)
+; CHECK: testb $1, %al
 
-define i32 @test5(double %d) nounwind {
+define i32 @test6(double %d) {
     %tmp = fptosi double %d to i1
     br i1 %tmp, label %cond_true, label %cond_false
 cond_true:
@@ -55,5 +51,4 @@ cond_true:
 cond_false:
     ret i32 42
 }
-; CHECK: test5:
 ; CHECK: testb $1
index 2d75c5d762010d77f64b82717688f6559067b334..a6bdb13ec6b41213e5205fcc587e6efd9c9b11ad 100644 (file)
@@ -1,6 +1,5 @@
 ; 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:
@@ -35,33 +34,3 @@ 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                          ; <i1> [#uses=1]
-  %1 = icmp eq i32 %y, 0                          ; <i1> [#uses=1]
-  %2 = xor i1 %1, %0                              ; <i1> [#uses=1]
-  br i1 %2, label %bb, label %return
-
-bb:                                               ; preds = %entry
-  %3 = tail call i32 (...)* @foo() nounwind       ; <i32> [#uses=0]
-  ret i32 undef
-
-return:                                           ; preds = %entry
-  ret i32 undef
-}