Skip to content

Commit f37d7c9

Browse files
committed
[AVR] Optimize 16-bit comparison with a constant
Fixes #30923 Reviewed By: jacquesguan, aykevl Differential Revision: https://reviews.llvm.org/D142281
1 parent eb8e1bf commit f37d7c9

File tree

2 files changed

+121
-1
lines changed

2 files changed

+121
-1
lines changed

llvm/lib/Target/AVR/AVRISelLowering.cpp

+25-1
Original file line numberDiff line numberDiff line change
@@ -634,11 +634,35 @@ SDValue AVRTargetLowering::getAVRCmp(SDValue LHS, SDValue RHS,
634634
SDValue Cmp;
635635

636636
if (LHS.getSimpleValueType() == MVT::i16 && isa<ConstantSDNode>(RHS)) {
637-
// Generate a CPI/CPC pair if RHS is a 16-bit constant.
637+
uint64_t Imm = cast<ConstantSDNode>(RHS)->getZExtValue();
638+
// Generate a CPI/CPC pair if RHS is a 16-bit constant. Use the zero
639+
// register for the constant RHS if its lower or higher byte is zero.
638640
SDValue LHSlo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, LHS,
639641
DAG.getIntPtrConstant(0, DL));
640642
SDValue LHShi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, LHS,
641643
DAG.getIntPtrConstant(1, DL));
644+
SDValue RHSlo = (Imm & 0xff) == 0
645+
? DAG.getRegister(Subtarget.getZeroRegister(), MVT::i8)
646+
: DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, RHS,
647+
DAG.getIntPtrConstant(0, DL));
648+
SDValue RHShi = (Imm & 0xff00) == 0
649+
? DAG.getRegister(Subtarget.getZeroRegister(), MVT::i8)
650+
: DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, RHS,
651+
DAG.getIntPtrConstant(1, DL));
652+
Cmp = DAG.getNode(AVRISD::CMP, DL, MVT::Glue, LHSlo, RHSlo);
653+
Cmp = DAG.getNode(AVRISD::CMPC, DL, MVT::Glue, LHShi, RHShi, Cmp);
654+
} else if (RHS.getSimpleValueType() == MVT::i16 && isa<ConstantSDNode>(LHS)) {
655+
// Generate a CPI/CPC pair if LHS is a 16-bit constant. Use the zero
656+
// register for the constant LHS if its lower or higher byte is zero.
657+
uint64_t Imm = cast<ConstantSDNode>(LHS)->getZExtValue();
658+
SDValue LHSlo = (Imm & 0xff) == 0
659+
? DAG.getRegister(Subtarget.getZeroRegister(), MVT::i8)
660+
: DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, LHS,
661+
DAG.getIntPtrConstant(0, DL));
662+
SDValue LHShi = (Imm & 0xff00) == 0
663+
? DAG.getRegister(Subtarget.getZeroRegister(), MVT::i8)
664+
: DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, LHS,
665+
DAG.getIntPtrConstant(1, DL));
642666
SDValue RHSlo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, RHS,
643667
DAG.getIntPtrConstant(0, DL));
644668
SDValue RHShi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, RHS,

llvm/test/CodeGen/AVR/cmp.ll

+96
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
; RUN: llc < %s -march=avr | FileCheck %s
2+
; RUN: llc < %s -mtriple=avr -mcpu=attiny10 | FileCheck --check-prefix=TINY %s
23

34
declare void @f1(i8)
45
declare void @f2(i8)
@@ -202,3 +203,98 @@ if.else:
202203
if.end:
203204
ret void
204205
}
206+
207+
define i16 @cmp_i16_gt_0(i16 %0) {
208+
; CHECK-LABEL: cmp_i16_gt_0:
209+
; CHECK: ; %bb.0:
210+
; CHECK-NEXT: ldi r18, 1
211+
; CHECK-NEXT: cp r1, r24
212+
; CHECK-NEXT: cpc r1, r25
213+
; CHECK-NEXT: brlt .LBB11_2
214+
; CHECK-NEXT: ; %bb.1:
215+
; CHECK-NEXT: mov r18, r1
216+
; CHECK-NEXT: .LBB11_2:
217+
; CHECK-NEXT: mov r24, r18
218+
; CHECK-NEXT: clr r25
219+
; CHECK-NEXT: ret
220+
;
221+
; TINY-LABEL: cmp_i16_gt_0:
222+
; TINY: ; %bb.0:
223+
; TINY-NEXT: ldi r20, 1
224+
; TINY-NEXT: cp r17, r24
225+
; TINY-NEXT: cpc r17, r25
226+
; TINY-NEXT: brlt .LBB11_2
227+
; TINY-NEXT: ; %bb.1:
228+
; TINY-NEXT: mov r20, r17
229+
; TINY-NEXT: .LBB11_2:
230+
; TINY-NEXT: mov r24, r20
231+
; TINY-NEXT: clr r25
232+
; TINY-NEXT: ret
233+
%2 = icmp sgt i16 %0, 0
234+
%3 = zext i1 %2 to i16
235+
ret i16 %3
236+
}
237+
238+
define i16 @cmp_i16_gt_126(i16 %0) {
239+
; CHECK-LABEL: cmp_i16_gt_126:
240+
; CHECK: ; %bb.0:
241+
; CHECK-NEXT: ldi r18, 1
242+
; CHECK-NEXT: cpi r24, 127
243+
; CHECK-NEXT: cpc r25, r1
244+
; CHECK-NEXT: brge .LBB12_2
245+
; CHECK-NEXT: ; %bb.1:
246+
; CHECK-NEXT: mov r18, r1
247+
; CHECK-NEXT: .LBB12_2:
248+
; CHECK-NEXT: mov r24, r18
249+
; CHECK-NEXT: clr r25
250+
; CHECK-NEXT: ret
251+
;
252+
; TINY-LABEL: cmp_i16_gt_126:
253+
; TINY: ; %bb.0:
254+
; TINY-NEXT: ldi r20, 1
255+
; TINY-NEXT: cpi r24, 127
256+
; TINY-NEXT: cpc r25, r17
257+
; TINY-NEXT: brge .LBB12_2
258+
; TINY-NEXT: ; %bb.1:
259+
; TINY-NEXT: mov r20, r17
260+
; TINY-NEXT: .LBB12_2:
261+
; TINY-NEXT: mov r24, r20
262+
; TINY-NEXT: clr r25
263+
; TINY-NEXT: ret
264+
%2 = icmp sgt i16 %0, 126
265+
%3 = zext i1 %2 to i16
266+
ret i16 %3
267+
}
268+
269+
define i16 @cmp_i16_gt_1023(i16 %0) {
270+
; CHECK-LABEL: cmp_i16_gt_1023:
271+
; CHECK: ; %bb.0:
272+
; CHECK-NEXT: ldi r19, 4
273+
; CHECK-NEXT: ldi r18, 1
274+
; CHECK-NEXT: cp r24, r1
275+
; CHECK-NEXT: cpc r25, r19
276+
; CHECK-NEXT: brge .LBB13_2
277+
; CHECK-NEXT: ; %bb.1:
278+
; CHECK-NEXT: mov r18, r1
279+
; CHECK-NEXT: .LBB13_2:
280+
; CHECK-NEXT: mov r24, r18
281+
; CHECK-NEXT: clr r25
282+
; CHECK-NEXT: ret
283+
;
284+
; TINY-LABEL: cmp_i16_gt_1023:
285+
; TINY: ; %bb.0:
286+
; TINY-NEXT: ldi r21, 4
287+
; TINY-NEXT: ldi r20, 1
288+
; TINY-NEXT: cp r24, r17
289+
; TINY-NEXT: cpc r25, r21
290+
; TINY-NEXT: brge .LBB13_2
291+
; TINY-NEXT: ; %bb.1:
292+
; TINY-NEXT: mov r20, r17
293+
; TINY-NEXT: .LBB13_2:
294+
; TINY-NEXT: mov r24, r20
295+
; TINY-NEXT: clr r25
296+
; TINY-NEXT: ret
297+
%2 = icmp sgt i16 %0, 1023
298+
%3 = zext i1 %2 to i16
299+
ret i16 %3
300+
}

0 commit comments

Comments
 (0)