Skip to content

Commit 1eb8c5c

Browse files
committed
[AVR] Optimize 16-bit comparison with constant
Reviewed By: dylanmckay Differential Revision: https://reviews.llvm.org/D93976
1 parent a6f0221 commit 1eb8c5c

File tree

3 files changed

+91
-3
lines changed

3 files changed

+91
-3
lines changed

llvm/lib/Target/AVR/AVRISelLowering.cpp

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,36 @@ static AVRCC::CondCodes intCCToAVRCC(ISD::CondCode CC) {
455455
}
456456
}
457457

458+
/// Returns appropriate CP/CPI/CPC nodes code for the given 8/16-bit operands.
459+
SDValue AVRTargetLowering::getAVRCmp(SDValue LHS, SDValue RHS,
460+
SelectionDAG &DAG, SDLoc DL) const {
461+
assert((LHS.getSimpleValueType() == RHS.getSimpleValueType()) &&
462+
"LHS and RHS have different types");
463+
assert(((LHS.getSimpleValueType() == MVT::i16) ||
464+
(LHS.getSimpleValueType() == MVT::i8)) && "invalid comparison type");
465+
466+
SDValue Cmp;
467+
468+
if (LHS.getSimpleValueType() == MVT::i16 && dyn_cast<ConstantSDNode>(RHS)) {
469+
// Generate a CPI/CPC pair if RHS is a 16-bit constant.
470+
SDValue LHSlo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, LHS,
471+
DAG.getIntPtrConstant(0, DL));
472+
SDValue LHShi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, LHS,
473+
DAG.getIntPtrConstant(1, DL));
474+
SDValue RHSlo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, RHS,
475+
DAG.getIntPtrConstant(0, DL));
476+
SDValue RHShi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, RHS,
477+
DAG.getIntPtrConstant(1, DL));
478+
Cmp = DAG.getNode(AVRISD::CMP, DL, MVT::Glue, LHSlo, RHSlo);
479+
Cmp = DAG.getNode(AVRISD::CMPC, DL, MVT::Glue, LHShi, RHShi, Cmp);
480+
} else {
481+
// Generate ordinary 16-bit comparison.
482+
Cmp = DAG.getNode(AVRISD::CMP, DL, MVT::Glue, LHS, RHS);
483+
}
484+
485+
return Cmp;
486+
}
487+
458488
/// Returns appropriate AVR CMP/CMPC nodes and corresponding condition code for
459489
/// the given operands.
460490
SDValue AVRTargetLowering::getAVRCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
@@ -567,7 +597,7 @@ SDValue AVRTargetLowering::getAVRCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
567597
DAG.getIntPtrConstant(1, DL));
568598
Cmp = DAG.getNode(AVRISD::TST, DL, MVT::Glue, Top);
569599
} else {
570-
Cmp = DAG.getNode(AVRISD::CMP, DL, MVT::Glue, LHSlo, RHSlo);
600+
Cmp = getAVRCmp(LHSlo, RHSlo, DAG, DL);
571601
Cmp = DAG.getNode(AVRISD::CMPC, DL, MVT::Glue, LHShi, RHShi, Cmp);
572602
}
573603
} else if (VT == MVT::i64) {
@@ -605,7 +635,7 @@ SDValue AVRTargetLowering::getAVRCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
605635
DAG.getIntPtrConstant(1, DL));
606636
Cmp = DAG.getNode(AVRISD::TST, DL, MVT::Glue, Top);
607637
} else {
608-
Cmp = DAG.getNode(AVRISD::CMP, DL, MVT::Glue, LHS0, RHS0);
638+
Cmp = getAVRCmp(LHS0, RHS0, DAG, DL);
609639
Cmp = DAG.getNode(AVRISD::CMPC, DL, MVT::Glue, LHS1, RHS1, Cmp);
610640
Cmp = DAG.getNode(AVRISD::CMPC, DL, MVT::Glue, LHS2, RHS2, Cmp);
611641
Cmp = DAG.getNode(AVRISD::CMPC, DL, MVT::Glue, LHS3, RHS3, Cmp);
@@ -619,7 +649,7 @@ SDValue AVRTargetLowering::getAVRCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
619649
: DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8,
620650
LHS, DAG.getIntPtrConstant(1, DL)));
621651
} else {
622-
Cmp = DAG.getNode(AVRISD::CMP, DL, MVT::Glue, LHS, RHS);
652+
Cmp = getAVRCmp(LHS, RHS, DAG, DL);
623653
}
624654
} else {
625655
llvm_unreachable("Invalid comparison size");

llvm/lib/Target/AVR/AVRISelLowering.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ class AVRTargetLowering : public TargetLowering {
138138
private:
139139
SDValue getAVRCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, SDValue &AVRcc,
140140
SelectionDAG &DAG, SDLoc dl) const;
141+
SDValue getAVRCmp(SDValue LHS, SDValue RHS, SelectionDAG &DAG,
142+
SDLoc dl) const;
141143
SDValue LowerShifts(SDValue Op, SelectionDAG &DAG) const;
142144
SDValue LowerDivRem(SDValue Op, SelectionDAG &DAG) const;
143145
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;

llvm/test/CodeGen/AVR/cmp.ll

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,22 @@ if.end:
3636
ret void
3737
}
3838

39+
define void @cmpimm16(i16 %a) {
40+
; CHECK-LABEL: cmpimm16:
41+
; CHECK: cpi
42+
; CHECK-NEXT: cpc
43+
%cmp = icmp eq i16 %a, 4567
44+
br i1 %cmp, label %if.then, label %if.else
45+
if.then:
46+
tail call void @f3(i16 %a)
47+
br label %if.end
48+
if.else:
49+
tail call void @f4(i16 %a)
50+
br label %if.end
51+
if.end:
52+
ret void
53+
}
54+
3955
declare void @f5(i32)
4056
declare void @f6(i32)
4157
define void @cmp32(i32 %a, i32 %b) {
@@ -56,6 +72,24 @@ if.end:
5672
ret void
5773
}
5874

75+
define void @cmpimm32(i32 %a) {
76+
; CHECK-LABEL: cmpimm32:
77+
; CHECK: cpi
78+
; CHECK-NEXT: cpc
79+
; CHECK-NEXT: cpc
80+
; CHECK-NEXT: cpc
81+
%cmp = icmp eq i32 %a, 6789343
82+
br i1 %cmp, label %if.then, label %if.else
83+
if.then:
84+
tail call void @f5(i32 %a)
85+
br label %if.end
86+
if.else:
87+
tail call void @f6(i32 %a)
88+
br label %if.end
89+
if.end:
90+
ret void
91+
}
92+
5993
declare void @f7(i64)
6094
declare void @f8(i64)
6195
define void @cmp64(i64 %a, i64 %b) {
@@ -80,6 +114,28 @@ if.end:
80114
ret void
81115
}
82116

117+
define void @cmpimm64(i64 %a) {
118+
; CHECK-LABEL: cmpimm64:
119+
; CHECK: cpi
120+
; CHECK-NEXT: cpc
121+
; CHECK-NEXT: cpc
122+
; CHECK-NEXT: cpc
123+
; CHECK-NEXT: cpc
124+
; CHECK-NEXT: cpc
125+
; CHECK-NEXT: cpc
126+
; CHECK-NEXT: cpc
127+
%cmp = icmp eq i64 %a, 234566452
128+
br i1 %cmp, label %if.then, label %if.else
129+
if.then:
130+
tail call void @f7(i64 %a)
131+
br label %if.end
132+
if.else:
133+
tail call void @f8(i64 %a)
134+
br label %if.end
135+
if.end:
136+
ret void
137+
}
138+
83139
declare void @f9()
84140
declare void @f10()
85141

0 commit comments

Comments
 (0)