llvm.org GIT mirror llvm / af4437e
[DAGCombiner] Fix issue with rotate combines asserting if the constant value types differ from the result type. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307900 91177308-0d34-0410-b5e6-96231b3b80d8 Simon Pilgrim 3 years ago
2 changed file(s) with 45 addition(s) and 15 deletion(s). Raw diff Collapse all Expand all
52845284
52855285 unsigned NextOp = N0.getOpcode();
52865286 // fold (rot* (rot* x, c2), c1) -> (rot* x, c1 +- c2 % bitsize)
5287 if (NextOp == ISD::ROTL || NextOp == ISD::ROTR)
5288 if (SDNode *C1 = DAG.isConstantIntBuildVectorOrConstantInt(N1))
5289 if (SDNode *C2 =
5290 DAG.isConstantIntBuildVectorOrConstantInt(N0.getOperand(1))) {
5291 bool SameSide = (N->getOpcode() == NextOp);
5292 unsigned CombineOp = SameSide ? ISD::ADD : ISD::SUB;
5293 if (SDValue CombinedShift =
5294 DAG.FoldConstantArithmetic(CombineOp, dl, VT, C1, C2)) {
5295 unsigned Bitsize = VT.getScalarSizeInBits();
5296 SDValue BitsizeC = DAG.getConstant(Bitsize, dl, VT);
5297 SDValue CombinedShiftNorm = DAG.FoldConstantArithmetic(
5298 ISD::SREM, dl, VT, CombinedShift.getNode(), BitsizeC.getNode());
5299 return DAG.getNode(
5300 N->getOpcode(), dl, VT, N0->getOperand(0), CombinedShiftNorm);
5301 }
5287 if (NextOp == ISD::ROTL || NextOp == ISD::ROTR) {
5288 SDNode *C1 = DAG.isConstantIntBuildVectorOrConstantInt(N1);
5289 SDNode *C2 = DAG.isConstantIntBuildVectorOrConstantInt(N0.getOperand(1));
5290 if (C1 && C2 && C1->getValueType(0) == C2->getValueType(0)) {
5291 EVT ShiftVT = C1->getValueType(0);
5292 bool SameSide = (N->getOpcode() == NextOp);
5293 unsigned CombineOp = SameSide ? ISD::ADD : ISD::SUB;
5294 if (SDValue CombinedShift =
5295 DAG.FoldConstantArithmetic(CombineOp, dl, ShiftVT, C1, C2)) {
5296 unsigned Bitsize = VT.getScalarSizeInBits();
5297 SDValue BitsizeC = DAG.getConstant(Bitsize, dl, ShiftVT);
5298 SDValue CombinedShiftNorm = DAG.FoldConstantArithmetic(
5299 ISD::SREM, dl, ShiftVT, CombinedShift.getNode(),
5300 BitsizeC.getNode());
5301 return DAG.getNode(N->getOpcode(), dl, VT, N0->getOperand(0),
5302 CombinedShiftNorm);
53025303 }
5304 }
5305 }
53035306 return SDValue();
53045307 }
53055308
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc < %s -mtriple=i686-unknown-unknown -mcpu=i686 | FileCheck %s --check-prefix=X86
2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=X64
3
4 ; Combine BSWAP (lowered to rolw 8) with a second rotate.
5 ; This test checks for combining rotates with inconsistent constant value types.
6
7 define i16 @combine_bswap_rotate(i16 %a0) {
8 ; X86-LABEL: combine_bswap_rotate:
9 ; X86: # BB#0:
10 ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
11 ; X86-NEXT: rolw $9, %ax
12 ; X86-NEXT: retl
13 ;
14 ; X64-LABEL: combine_bswap_rotate:
15 ; X64: # BB#0:
16 ; X64-NEXT: rolw $9, %di
17 ; X64-NEXT: movl %edi, %eax
18 ; X64-NEXT: retq
19 %1 = call i16 @llvm.bswap.i16(i16 %a0)
20 %2 = shl i16 %1, 1
21 %3 = lshr i16 %1, 15
22 %4 = or i16 %2, %3
23 ret i16 %4
24 }
25
26 declare i16 @llvm.bswap.i16(i16)