Skip to content

Commit 27ae4c3

Browse files
author
Strahinja Petrovic
committedMay 9, 2017
[MIPS] Add support to match more patterns for DINS instruction
This patch adds support for recognizing patterns to match DINS instruction. Differential Revision: https://reviews.llvm.org/D31465 llvm-svn: 302512
1 parent 95640a1 commit 27ae4c3

File tree

3 files changed

+133
-30
lines changed

3 files changed

+133
-30
lines changed
 

‎llvm/lib/Target/Mips/MipsISelLowering.cpp

+59-25
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,7 @@ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
795795

796796
SDValue And0 = N->getOperand(0), And1 = N->getOperand(1);
797797
uint64_t SMPos0, SMSize0, SMPos1, SMSize1;
798-
ConstantSDNode *CN;
798+
ConstantSDNode *CN, *CN1;
799799

800800
// See if Op's first operand matches (and $src1 , mask0).
801801
if (And0.getOpcode() != ISD::AND)
@@ -806,37 +806,71 @@ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
806806
return SDValue();
807807

808808
// See if Op's second operand matches (and (shl $src, pos), mask1).
809-
if (And1.getOpcode() != ISD::AND)
810-
return SDValue();
809+
if (And1.getOpcode() == ISD::AND &&
810+
And1.getOperand(0).getOpcode() == ISD::SHL) {
811811

812-
if (!(CN = dyn_cast<ConstantSDNode>(And1.getOperand(1))) ||
813-
!isShiftedMask(CN->getZExtValue(), SMPos1, SMSize1))
814-
return SDValue();
812+
if (!(CN = dyn_cast<ConstantSDNode>(And1.getOperand(1))) ||
813+
!isShiftedMask(CN->getZExtValue(), SMPos1, SMSize1))
814+
return SDValue();
815815

816-
// The shift masks must have the same position and size.
817-
if (SMPos0 != SMPos1 || SMSize0 != SMSize1)
818-
return SDValue();
816+
// The shift masks must have the same position and size.
817+
if (SMPos0 != SMPos1 || SMSize0 != SMSize1)
818+
return SDValue();
819819

820-
SDValue Shl = And1.getOperand(0);
821-
if (Shl.getOpcode() != ISD::SHL)
822-
return SDValue();
820+
SDValue Shl = And1.getOperand(0);
823821

824-
if (!(CN = dyn_cast<ConstantSDNode>(Shl.getOperand(1))))
825-
return SDValue();
822+
if (!(CN = dyn_cast<ConstantSDNode>(Shl.getOperand(1))))
823+
return SDValue();
826824

827-
unsigned Shamt = CN->getZExtValue();
825+
unsigned Shamt = CN->getZExtValue();
828826

829-
// Return if the shift amount and the first bit position of mask are not the
830-
// same.
831-
EVT ValTy = N->getValueType(0);
832-
if ((Shamt != SMPos0) || (SMPos0 + SMSize0 > ValTy.getSizeInBits()))
833-
return SDValue();
827+
// Return if the shift amount and the first bit position of mask are not the
828+
// same.
829+
EVT ValTy = N->getValueType(0);
830+
if ((Shamt != SMPos0) || (SMPos0 + SMSize0 > ValTy.getSizeInBits()))
831+
return SDValue();
834832

835-
SDLoc DL(N);
836-
return DAG.getNode(MipsISD::Ins, DL, ValTy, Shl.getOperand(0),
837-
DAG.getConstant(SMPos0, DL, MVT::i32),
838-
DAG.getConstant(SMSize0, DL, MVT::i32),
839-
And0.getOperand(0));
833+
SDLoc DL(N);
834+
return DAG.getNode(MipsISD::Ins, DL, ValTy, Shl.getOperand(0),
835+
DAG.getConstant(SMPos0, DL, MVT::i32),
836+
DAG.getConstant(SMSize0, DL, MVT::i32),
837+
And0.getOperand(0));
838+
} else {
839+
// Pattern match DINS.
840+
// $dst = or (and $src, mask0), mask1
841+
// where mask0 = ((1 << SMSize0) -1) << SMPos0
842+
// => dins $dst, $src, pos, size
843+
if (~CN->getSExtValue() == ((((int64_t)1 << SMSize0) - 1) << SMPos0) &&
844+
((SMSize0 + SMPos0 <= 64 && Subtarget.hasMips64r2()) ||
845+
(SMSize0 + SMPos0 <= 32))) {
846+
// Check if AND instruction has constant as argument
847+
bool isConstCase = And1.getOpcode() != ISD::AND;
848+
if (And1.getOpcode() == ISD::AND) {
849+
if (!(CN1 = dyn_cast<ConstantSDNode>(And1->getOperand(1))))
850+
return SDValue();
851+
} else {
852+
if (!(CN1 = dyn_cast<ConstantSDNode>(N->getOperand(1))))
853+
return SDValue();
854+
}
855+
SDLoc DL(N);
856+
EVT ValTy = N->getOperand(0)->getValueType(0);
857+
SDValue Const1;
858+
SDValue SrlX;
859+
if (!isConstCase) {
860+
Const1 = DAG.getConstant(SMPos0, DL, MVT::i32);
861+
SrlX = DAG.getNode(ISD::SRL, DL, And1->getValueType(0), And1, Const1);
862+
}
863+
return DAG.getNode(
864+
MipsISD::Ins, DL, N->getValueType(0),
865+
isConstCase
866+
? DAG.getConstant(CN1->getSExtValue() >> SMPos0, DL, ValTy)
867+
: SrlX,
868+
DAG.getConstant(SMPos0, DL, MVT::i32),
869+
DAG.getConstant(SMSize0, DL, MVT::i32), And0->getOperand(0));
870+
871+
}
872+
return SDValue();
873+
}
840874
}
841875

842876
static SDValue performADDCombine(SDNode *N, SelectionDAG &DAG,

‎llvm/test/CodeGen/Mips/dins.ll

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
; RUN: llc -O2 -march=mips64 -mcpu=mips64r2 -target-abi=n64 < %s -o - | FileCheck %s -check-prefix=MIPS64R2
2+
; RUN: llc -O2 -march=mips -mcpu=mips32r2 < %s -o - | FileCheck %s -check-prefix=MIPS32R2
3+
; RUN: llc -O2 -march=mips -mattr=mips16 < %s -o - | FileCheck %s -check-prefix=MIPS16
4+
5+
; #include <stdint.h>
6+
; #include <stdio.h>
7+
; struct cvmx_buf_ptr {
8+
9+
; struct {
10+
; unsigned long long addr :37;
11+
; unsigned long long addr1 :15;
12+
; unsigned int lenght:14;
13+
; uint64_t total_bytes:16;
14+
; uint64_t segs : 6;
15+
; } s;
16+
; }
17+
;
18+
; unsigned long long foo(volatile struct cvmx_buf_ptr bufptr) {
19+
; bufptr.s.addr = 123;
20+
; bufptr.s.segs = 4;
21+
; bufptr.s.lenght = 5;
22+
; bufptr.s.total_bytes = bufptr.s.lenght;
23+
; return bufptr.s.addr;
24+
; }
25+
26+
; Testing of selection INS/DINS instruction
27+
28+
define i64 @f123(i64 inreg %bufptr.coerce0, i64 inreg %bufptr.coerce1) local_unnamed_addr #0 {
29+
entry:
30+
%bufptr.sroa.0 = alloca i64, align 8
31+
%bufptr.sroa.4 = alloca i64, align 8
32+
store i64 %bufptr.coerce0, i64* %bufptr.sroa.0, align 8
33+
store i64 %bufptr.coerce1, i64* %bufptr.sroa.4, align 8
34+
%bufptr.sroa.0.0.bufptr.sroa.0.0.bufptr.sroa.0.0.bf.load = load volatile i64, i64* %bufptr.sroa.0, align 8
35+
%bf.clear = and i64 %bufptr.sroa.0.0.bufptr.sroa.0.0.bufptr.sroa.0.0.bf.load, 134217727
36+
%bf.set = or i64 %bf.clear, 16508780544
37+
store volatile i64 %bf.set, i64* %bufptr.sroa.0, align 8
38+
%bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load2 = load volatile i64, i64* %bufptr.sroa.4, align 8
39+
%bf.clear3 = and i64 %bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load2, -16911433729
40+
%bf.set4 = or i64 %bf.clear3, 1073741824
41+
store volatile i64 %bf.set4, i64* %bufptr.sroa.4, align 8
42+
%bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load6 = load volatile i64, i64* %bufptr.sroa.4, align 8
43+
%bf.clear7 = and i64 %bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load6, 1125899906842623
44+
%bf.set8 = or i64 %bf.clear7, 5629499534213120
45+
store volatile i64 %bf.set8, i64* %bufptr.sroa.4, align 8
46+
%bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load11 = load volatile i64, i64* %bufptr.sroa.4, align 8
47+
%bf.lshr = lshr i64 %bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load11, 50
48+
%bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load13 = load volatile i64, i64* %bufptr.sroa.4, align 8
49+
%bf.shl = shl nuw nsw i64 %bf.lshr, 34
50+
%bf.clear14 = and i64 %bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load13, -1125882726973441
51+
%bf.set15 = or i64 %bf.clear14, %bf.shl
52+
store volatile i64 %bf.set15, i64* %bufptr.sroa.4, align 8
53+
%bufptr.sroa.0.0.bufptr.sroa.0.0.bufptr.sroa.0.0.bf.load17 = load volatile i64, i64* %bufptr.sroa.0, align 8
54+
%bf.lshr18 = lshr i64 %bufptr.sroa.0.0.bufptr.sroa.0.0.bufptr.sroa.0.0.bf.load17, 27
55+
ret i64 %bf.lshr18
56+
}
57+
58+
59+
; CHECK-LABEL: f123:
60+
; MIPS64R2: daddiu $[[R0:[0-9]+]], $zero, 123
61+
; MIPS64R2: dins $[[R0:[0-9]+]], $[[R1:[0-9]+]], 27, 37
62+
; MIPS64R2: daddiu $[[R0:[0-9]+]], $zero, 5
63+
; MIPS64R2: daddiu $[[R0:[0-9]+]], $zero, 4
64+
; MIPS64R2: dins $[[R0:[0-9]+]], $[[R1:[0-9]+]], 28, 6
65+
; MIPS64R2: dins $[[R0:[0-9]+]], $[[R1:[0-9]+]], 50, 14
66+
; MIPS64R2: dsrl $[[R0:[0-9]+]], $[[R1:[0-9]+]], 50
67+
; MIPS64R2: dins $[[R0:[0-9]+]], $[[R1:[0-9]+]], 34, 16
68+
; MIPS32R2: ins $[[R0:[0-9]+]], $[[R1:[0-9]+]], 2, 16
69+
; MIPS32R2-NOT: ins $[[R0:[0-9]+]], $[[R1:[0-9]+]], 18, 46
70+
; MIPS16-NOT: ins{{[[:space:]].*}}

‎llvm/test/CodeGen/Mips/mips64-f128.ll

+4-5
Original file line numberDiff line numberDiff line change
@@ -418,18 +418,17 @@ entry:
418418
declare fp128 @llvm.powi.f128(fp128, i32) #3
419419

420420
; ALL-LABEL: libcall2_copysignl:
421-
; ALL-DAG: daddiu $[[R2:[0-9]+]], $zero, 1
422-
; ALL-DAG: dsll $[[R3:[0-9]+]], $[[R2]], 63
421+
; NOT-R2R6-DAG: daddiu $[[R2:[0-9]+]], $zero, 1
422+
; NOT-R2R6-DAG: dsll $[[R3:[0-9]+]], $[[R2]], 63
423423
; ALL-DAG: ld $[[R0:[0-9]+]], %got_disp(gld1)
424424
; ALL-DAG: ld $[[R1:[0-9]+]], 8($[[R0]])
425-
; ALL-DAG: and $[[R4:[0-9]+]], $[[R1]], $[[R3]]
425+
; NOT-R2R6-DAG: and $[[R4:[0-9]+]], $[[R1]], $[[R3]]
426426
; ALL-DAG: ld $[[R5:[0-9]+]], %got_disp(gld0)
427427
; ALL-DAG: ld $[[R6:[0-9]+]], 8($[[R5]])
428+
; R2R6: dins $[[R0:[0-9]+]], $[[R1:[0-9]+]], 63, 1
428429
; NOT-R2R6-DAG: daddiu $[[R7:[0-9]+]], $[[R3]], -1
429430
; NOT-R2R6-DAG: and $[[R8:[0-9]+]], $[[R6]], $[[R7]]
430431
; NOT-R2R6-DAG: or $4, $[[R8]], $[[R4]]
431-
; R2R6-DAG: dextm $[[R7:[0-9]+]], $[[R6]], 0, 63
432-
; R2R6-DAG: or $4, $[[R7]], $[[R4]]
433432
; ALL-DAG: ld $2, 0($[[R5]])
434433

435434
define fp128 @libcall2_copysignl() {

0 commit comments

Comments
 (0)