Skip to content

Commit a2ea8c7

Browse files
Nikola PericNikola Peric
authored andcommitted
NanoMips: OR combine optimization
Combine OR into INS when there is no masking for the second register but it holds zero extended value whose original width is less than equal to the number of bits from the first register set to zero.
1 parent 6b08e39 commit a2ea8c7

File tree

2 files changed

+53
-2
lines changed

2 files changed

+53
-2
lines changed

llvm/lib/Target/Mips/MipsISelLowering.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,9 +1129,20 @@ static SDValue attemptOrToIns(SDValue &And, SDValue &Right, SDNode *N,
11291129
if (!(CN = dyn_cast<ConstantSDNode>(Right.getOperand(1))))
11301130
return SDValue();
11311131
unsigned ShiftAmount = CN->getZExtValue();
1132-
// Second check makes sure that all upper bits are picked up.
1133-
if ((ShiftAmount != SMPos0) || (SMPos0 + SMSize0 != TSize))
1132+
1133+
if ((ShiftAmount != SMPos0))
11341134
return SDValue();
1135+
1136+
if ((SMPos0 + SMSize0 != TSize)) {
1137+
// If a register holds a value that is zero extended
1138+
// and if the actual size of that value can fit in SMSize0
1139+
// then we will allow replacement with the INS instruction
1140+
// because we are sure that we have only leading zeros
1141+
KnownBits Known = DAG.computeKnownBits(Right.getOperand(0));
1142+
if (Known.countMaxPopulation() > SMSize0)
1143+
return SDValue();
1144+
}
1145+
11351146
return DAG.getNode(MipsISD::Ins, DL, ValTy, Right.getOperand(0),
11361147
DAG.getConstant(SMPos0, DL, MVT::i32),
11371148
DAG.getConstant(SMSize0, DL, MVT::i32),

llvm/test/CodeGen/Mips/nanomips/ins.ll

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,43 @@ define i32 @ins6(i32 %a, i32 %b) {
6060
%or = or i32 %and1, %shift
6161
ret i32 %or
6262
}
63+
64+
define i32 @ins7(i32 %a, i8 %b) {
65+
; CHECK: ins $a0, $a1, 16, 8
66+
%and1 = and i32 %a, 4278255615 ; 0xff00ffff
67+
%conv = zext i8 %b to i32
68+
%shift = shl i32 %conv, 16
69+
%or = or i32 %and1, %shift
70+
ret i32 %or
71+
}
72+
73+
define i32 @ins8(i32 %a, i16 %b) {
74+
; CHECK: ins $a0, $a1, 8, 16
75+
%and1 = and i32 %a, 4278190335 ; 0xff0000ff
76+
%conv = zext i16 %b to i32
77+
%shift = shl i32 %conv, 8
78+
%or = or i32 %and1, %shift
79+
ret i32 %or
80+
}
81+
82+
define i32 @ins9(i32 %a, i8* %b) {
83+
; CHECK: ins $a0, $a1, 16, 8
84+
%val = load i8, i8* %b
85+
%and1 = and i32 %a, 4278255615 ; 0xff00ffff
86+
%conv = zext i8 %val to i32
87+
%shift = shl i32 %conv, 16
88+
%or = or i32 %and1, %shift
89+
ret i32 %or
90+
}
91+
92+
define i32 @ins10(i32 %a, i16* %b) {
93+
; CHECK: ins $a0, $a1, 8, 16
94+
%val = load i16, i16* %b
95+
%and1 = and i32 %a, 4278190335 ; 0xff0000ff
96+
%conv = zext i16 %val to i32
97+
%shift = shl i32 %conv, 8
98+
%or = or i32 %and1, %shift
99+
ret i32 %or
100+
}
101+
102+

0 commit comments

Comments
 (0)