llvm.org GIT mirror llvm / 5cbd37e
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 Dan Gohman 10 years ago
2 changed file(s) with 29 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
19291929
19301930 // fold (or x, undef) -> -1
19311931 if (N0.getOpcode() == ISD::UNDEF || N1.getOpcode() == ISD::UNDEF)
1932 return DAG.getConstant(~0ULL, VT);
1932 return DAG.getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), VT);
19331933 // fold (or c1, c2) -> c1|c2
19341934 if (N0C && N1C)
19351935 return DAG.FoldConstantArithmetic(ISD::OR, VT, N0C, N1C);
24762476 uint64_t c1 = cast(N0.getOperand(1))->getZExtValue();
24772477 if (c1 < VT.getSizeInBits()) {
24782478 uint64_t c2 = N1C->getZExtValue();
2479 SDValue HiBitsMask =
2480 DAG.getConstant(APInt::getHighBitsSet(VT.getSizeInBits(),
2481 VT.getSizeInBits() - c1),
2482 VT);
24792483 SDValue Mask = DAG.getNode(ISD::AND, N0.getDebugLoc(), VT,
24802484 N0.getOperand(0),
2481 DAG.getConstant(~0ULL << c1, VT));
2485 HiBitsMask);
24822486 if (c2 > c1)
24832487 return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, Mask,
24842488 DAG.getConstant(c2-c1, N1.getValueType()));
24882492 }
24892493 }
24902494 // fold (shl (sra x, c1), c1) -> (and x, (shl -1, c1))
2491 if (N1C && N0.getOpcode() == ISD::SRA && N1 == N0.getOperand(1))
2495 if (N1C && N0.getOpcode() == ISD::SRA && N1 == N0.getOperand(1)) {
2496 SDValue HiBitsMask =
2497 DAG.getConstant(APInt::getHighBitsSet(VT.getSizeInBits(),
2498 VT.getSizeInBits() -
2499 N1C->getZExtValue()),
2500 VT);
24922501 return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, N0.getOperand(0),
2493 DAG.getConstant(~0ULL << N1C->getZExtValue(), VT));
2502 HiBitsMask);
2503 }
24942504
24952505 return N1C ? visitShiftByConstant(N, N1C->getZExtValue()) : SDValue();
24962506 }
30933103 }
30943104
30953105 // sext(setcc x, y, cc) -> (select_cc x, y, -1, 0, cc)
3106 SDValue NegOne =
3107 DAG.getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), VT);
30963108 SDValue SCC =
30973109 SimplifySelectCC(N->getDebugLoc(), N0.getOperand(0), N0.getOperand(1),
3098 DAG.getConstant(~0ULL, VT), DAG.getConstant(0, VT),
3110 NegOne, DAG.getConstant(0, VT),
30993111 cast(N0.getOperand(2))->get(), true);
31003112 if (SCC.getNode()) return SCC;
31013113 }
0 ; RUN: llvm-as < %s | llc -march=x86-64 | FileCheck %s
1 ; CHECK: movq $-65535, %rax
2
3 ; DAGCombiner should fold this to a simple constant.
4
5 define i64 @foo(i192 %a) nounwind {
6 %t = or i192 %a, -22300404916163702203072254898040925442801665
7 %s = and i192 %t, -22300404916163702203072254898040929737768960
8 %u = lshr i192 %s, 128
9 %v = trunc i192 %u to i64
10 ret i64 %v
11 }