Skip to content

Commit

Permalink
Revert commits 96556 and 96640, because commit 96556 breaks the
Browse files Browse the repository at this point in the history
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
  • Loading branch information
CunningBaldrick committed Feb 19, 2010
1 parent d035023 commit 3eba667
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 158 deletions.
52 changes: 2 additions & 50 deletions lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4655,62 +4655,14 @@ 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!
}
}
}
}

// 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();
}
Expand Down Expand Up @@ -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);
Expand Down
34 changes: 4 additions & 30 deletions lib/CodeGen/SelectionDAG/TargetLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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);
Expand All @@ -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)) &&
Expand All @@ -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);
}
}
}

Expand Down
48 changes: 16 additions & 32 deletions lib/Target/X86/X86ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion test/CodeGen/X86/critical-edge-split.ll
Original file line number Diff line number Diff line change
@@ -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" }
Expand Down
2 changes: 1 addition & 1 deletion test/CodeGen/X86/ins_subreg_coalesce-3.ll
Original file line number Diff line number Diff line change
@@ -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 }
Expand Down
21 changes: 8 additions & 13 deletions test/CodeGen/X86/trunc-to-bool.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -33,27 +31,24 @@ 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:
ret i32 21
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:
ret i32 21
cond_false:
ret i32 42
}
; CHECK: test5:
; CHECK: testb $1
31 changes: 0 additions & 31 deletions test/CodeGen/X86/xor-icmp.ll
Original file line number Diff line number Diff line change
@@ -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:
Expand Down Expand Up @@ -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
}

0 comments on commit 3eba667

Please sign in to comment.