mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-19 01:48:34 +00:00
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
This commit is contained in:
parent
186fa1d0df
commit
5cbd37e505
@ -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<ConstantSDNode>(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<CondCodeSDNode>(N0.getOperand(2))->get(), true);
|
||||
if (SCC.getNode()) return SCC;
|
||||
}
|
||||
|
12
test/CodeGen/X86/wide-integer-fold.ll
Normal file
12
test/CodeGen/X86/wide-integer-fold.ll
Normal file
@ -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
|
||||
}
|
Loading…
Reference in New Issue
Block a user