diff --git a/llvm/lib/Target/AVR/AVRISelLowering.cpp b/llvm/lib/Target/AVR/AVRISelLowering.cpp index ee2c4891797143..6c60d87c4704f7 100644 --- a/llvm/lib/Target/AVR/AVRISelLowering.cpp +++ b/llvm/lib/Target/AVR/AVRISelLowering.cpp @@ -634,11 +634,35 @@ SDValue AVRTargetLowering::getAVRCmp(SDValue LHS, SDValue RHS, SDValue Cmp; if (LHS.getSimpleValueType() == MVT::i16 && isa(RHS)) { - // Generate a CPI/CPC pair if RHS is a 16-bit constant. + uint64_t Imm = cast(RHS)->getZExtValue(); + // Generate a CPI/CPC pair if RHS is a 16-bit constant. Use the zero + // register for the constant RHS if its lower or higher byte is zero. SDValue LHSlo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, LHS, DAG.getIntPtrConstant(0, DL)); SDValue LHShi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, LHS, DAG.getIntPtrConstant(1, DL)); + SDValue RHSlo = (Imm & 0xff) == 0 + ? DAG.getRegister(Subtarget.getZeroRegister(), MVT::i8) + : DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, RHS, + DAG.getIntPtrConstant(0, DL)); + SDValue RHShi = (Imm & 0xff00) == 0 + ? DAG.getRegister(Subtarget.getZeroRegister(), MVT::i8) + : DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, RHS, + DAG.getIntPtrConstant(1, DL)); + Cmp = DAG.getNode(AVRISD::CMP, DL, MVT::Glue, LHSlo, RHSlo); + Cmp = DAG.getNode(AVRISD::CMPC, DL, MVT::Glue, LHShi, RHShi, Cmp); + } else if (RHS.getSimpleValueType() == MVT::i16 && isa(LHS)) { + // Generate a CPI/CPC pair if LHS is a 16-bit constant. Use the zero + // register for the constant LHS if its lower or higher byte is zero. + uint64_t Imm = cast(LHS)->getZExtValue(); + SDValue LHSlo = (Imm & 0xff) == 0 + ? DAG.getRegister(Subtarget.getZeroRegister(), MVT::i8) + : DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, LHS, + DAG.getIntPtrConstant(0, DL)); + SDValue LHShi = (Imm & 0xff00) == 0 + ? DAG.getRegister(Subtarget.getZeroRegister(), MVT::i8) + : DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, LHS, + DAG.getIntPtrConstant(1, DL)); SDValue RHSlo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, RHS, DAG.getIntPtrConstant(0, DL)); SDValue RHShi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, RHS, diff --git a/llvm/test/CodeGen/AVR/cmp.ll b/llvm/test/CodeGen/AVR/cmp.ll index e9769068f911df..715a3f1c9c18e3 100644 --- a/llvm/test/CodeGen/AVR/cmp.ll +++ b/llvm/test/CodeGen/AVR/cmp.ll @@ -1,4 +1,5 @@ ; RUN: llc < %s -march=avr | FileCheck %s +; RUN: llc < %s -mtriple=avr -mcpu=attiny10 | FileCheck --check-prefix=TINY %s declare void @f1(i8) declare void @f2(i8) @@ -202,3 +203,98 @@ if.else: if.end: ret void } + +define i16 @cmp_i16_gt_0(i16 %0) { +; CHECK-LABEL: cmp_i16_gt_0: +; CHECK: ; %bb.0: +; CHECK-NEXT: ldi r18, 1 +; CHECK-NEXT: cp r1, r24 +; CHECK-NEXT: cpc r1, r25 +; CHECK-NEXT: brlt .LBB11_2 +; CHECK-NEXT: ; %bb.1: +; CHECK-NEXT: mov r18, r1 +; CHECK-NEXT: .LBB11_2: +; CHECK-NEXT: mov r24, r18 +; CHECK-NEXT: clr r25 +; CHECK-NEXT: ret +; +; TINY-LABEL: cmp_i16_gt_0: +; TINY: ; %bb.0: +; TINY-NEXT: ldi r20, 1 +; TINY-NEXT: cp r17, r24 +; TINY-NEXT: cpc r17, r25 +; TINY-NEXT: brlt .LBB11_2 +; TINY-NEXT: ; %bb.1: +; TINY-NEXT: mov r20, r17 +; TINY-NEXT: .LBB11_2: +; TINY-NEXT: mov r24, r20 +; TINY-NEXT: clr r25 +; TINY-NEXT: ret + %2 = icmp sgt i16 %0, 0 + %3 = zext i1 %2 to i16 + ret i16 %3 +} + +define i16 @cmp_i16_gt_126(i16 %0) { +; CHECK-LABEL: cmp_i16_gt_126: +; CHECK: ; %bb.0: +; CHECK-NEXT: ldi r18, 1 +; CHECK-NEXT: cpi r24, 127 +; CHECK-NEXT: cpc r25, r1 +; CHECK-NEXT: brge .LBB12_2 +; CHECK-NEXT: ; %bb.1: +; CHECK-NEXT: mov r18, r1 +; CHECK-NEXT: .LBB12_2: +; CHECK-NEXT: mov r24, r18 +; CHECK-NEXT: clr r25 +; CHECK-NEXT: ret +; +; TINY-LABEL: cmp_i16_gt_126: +; TINY: ; %bb.0: +; TINY-NEXT: ldi r20, 1 +; TINY-NEXT: cpi r24, 127 +; TINY-NEXT: cpc r25, r17 +; TINY-NEXT: brge .LBB12_2 +; TINY-NEXT: ; %bb.1: +; TINY-NEXT: mov r20, r17 +; TINY-NEXT: .LBB12_2: +; TINY-NEXT: mov r24, r20 +; TINY-NEXT: clr r25 +; TINY-NEXT: ret + %2 = icmp sgt i16 %0, 126 + %3 = zext i1 %2 to i16 + ret i16 %3 +} + +define i16 @cmp_i16_gt_1023(i16 %0) { +; CHECK-LABEL: cmp_i16_gt_1023: +; CHECK: ; %bb.0: +; CHECK-NEXT: ldi r19, 4 +; CHECK-NEXT: ldi r18, 1 +; CHECK-NEXT: cp r24, r1 +; CHECK-NEXT: cpc r25, r19 +; CHECK-NEXT: brge .LBB13_2 +; CHECK-NEXT: ; %bb.1: +; CHECK-NEXT: mov r18, r1 +; CHECK-NEXT: .LBB13_2: +; CHECK-NEXT: mov r24, r18 +; CHECK-NEXT: clr r25 +; CHECK-NEXT: ret +; +; TINY-LABEL: cmp_i16_gt_1023: +; TINY: ; %bb.0: +; TINY-NEXT: ldi r21, 4 +; TINY-NEXT: ldi r20, 1 +; TINY-NEXT: cp r24, r17 +; TINY-NEXT: cpc r25, r21 +; TINY-NEXT: brge .LBB13_2 +; TINY-NEXT: ; %bb.1: +; TINY-NEXT: mov r20, r17 +; TINY-NEXT: .LBB13_2: +; TINY-NEXT: mov r24, r20 +; TINY-NEXT: clr r25 +; TINY-NEXT: ret + %2 = icmp sgt i16 %0, 1023 + %3 = zext i1 %2 to i16 + ret i16 %3 +}