From 5cbd37e5056f6a715333553e9d529e0ddddb3e78 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 6 Aug 2009 09:18:59 +0000 Subject: [PATCH] Fix a few places in DAGCombiner that were creating all-ones-bits and high-bits values in ways that weren't correct for integer types wider than 64 bits. This fixes a miscompile in PPMacroExpansion.cpp in clang on x86-64. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78295 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 22 +++++++++++++++++----- test/CodeGen/X86/wide-integer-fold.ll | 12 ++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 test/CodeGen/X86/wide-integer-fold.ll diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 7f2c91bc5c0..3d0f337c709 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1930,7 +1930,7 @@ SDValue DAGCombiner::visitOR(SDNode *N) { // fold (or x, undef) -> -1 if (N0.getOpcode() == ISD::UNDEF || N1.getOpcode() == ISD::UNDEF) - return DAG.getConstant(~0ULL, VT); + return DAG.getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), VT); // fold (or c1, c2) -> c1|c2 if (N0C && N1C) return DAG.FoldConstantArithmetic(ISD::OR, VT, N0C, N1C); @@ -2477,9 +2477,13 @@ SDValue DAGCombiner::visitSHL(SDNode *N) { uint64_t c1 = cast(N0.getOperand(1))->getZExtValue(); if (c1 < VT.getSizeInBits()) { uint64_t c2 = N1C->getZExtValue(); + SDValue HiBitsMask = + DAG.getConstant(APInt::getHighBitsSet(VT.getSizeInBits(), + VT.getSizeInBits() - c1), + VT); SDValue Mask = DAG.getNode(ISD::AND, N0.getDebugLoc(), VT, N0.getOperand(0), - DAG.getConstant(~0ULL << c1, VT)); + HiBitsMask); if (c2 > c1) return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, Mask, DAG.getConstant(c2-c1, N1.getValueType())); @@ -2489,9 +2493,15 @@ SDValue DAGCombiner::visitSHL(SDNode *N) { } } // fold (shl (sra x, c1), c1) -> (and x, (shl -1, c1)) - if (N1C && N0.getOpcode() == ISD::SRA && N1 == N0.getOperand(1)) + if (N1C && N0.getOpcode() == ISD::SRA && N1 == N0.getOperand(1)) { + SDValue HiBitsMask = + DAG.getConstant(APInt::getHighBitsSet(VT.getSizeInBits(), + VT.getSizeInBits() - + N1C->getZExtValue()), + VT); return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, N0.getOperand(0), - DAG.getConstant(~0ULL << N1C->getZExtValue(), VT)); + HiBitsMask); + } return N1C ? visitShiftByConstant(N, N1C->getZExtValue()) : SDValue(); } @@ -3094,9 +3104,11 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) { } // sext(setcc x, y, cc) -> (select_cc x, y, -1, 0, cc) + SDValue NegOne = + DAG.getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), VT); SDValue SCC = SimplifySelectCC(N->getDebugLoc(), N0.getOperand(0), N0.getOperand(1), - DAG.getConstant(~0ULL, VT), DAG.getConstant(0, VT), + NegOne, DAG.getConstant(0, VT), cast(N0.getOperand(2))->get(), true); if (SCC.getNode()) return SCC; } diff --git a/test/CodeGen/X86/wide-integer-fold.ll b/test/CodeGen/X86/wide-integer-fold.ll new file mode 100644 index 00000000000..64c6d98616b --- /dev/null +++ b/test/CodeGen/X86/wide-integer-fold.ll @@ -0,0 +1,12 @@ +; RUN: llvm-as < %s | llc -march=x86-64 | FileCheck %s +; CHECK: movq $-65535, %rax + +; DAGCombiner should fold this to a simple constant. + +define i64 @foo(i192 %a) nounwind { + %t = or i192 %a, -22300404916163702203072254898040925442801665 + %s = and i192 %t, -22300404916163702203072254898040929737768960 + %u = lshr i192 %s, 128 + %v = trunc i192 %u to i64 + ret i64 %v +} -- 2.34.1