Author: Ben Shi Date: 2021-01-23T23:54:16+08:00 New Revision: 25531a1d9657897e648d93f776a3abb70e9816ef
URL: https://github.com/llvm/llvm-project/commit/25531a1d9657897e648d93f776a3abb70e9816ef DIFF: https://github.com/llvm/llvm-project/commit/25531a1d9657897e648d93f776a3abb70e9816ef.diff LOG: [AVR] Optimize 8-bit logic left/right shifts Reviewed By: dylanmckay Differential Revision: https://reviews.llvm.org/D89047 Added: Modified: llvm/lib/Target/AVR/AVRISelLowering.cpp llvm/lib/Target/AVR/AVRISelLowering.h llvm/lib/Target/AVR/AVRInstrInfo.td llvm/test/CodeGen/AVR/ctlz.ll llvm/test/CodeGen/AVR/ctpop.ll llvm/test/CodeGen/AVR/cttz.ll llvm/test/CodeGen/AVR/shift.ll Removed: ################################################################################ diff --git a/llvm/lib/Target/AVR/AVRISelLowering.cpp b/llvm/lib/Target/AVR/AVRISelLowering.cpp index 9a464d0a52d8..bd5fd266d395 100644 --- a/llvm/lib/Target/AVR/AVRISelLowering.cpp +++ b/llvm/lib/Target/AVR/AVRISelLowering.cpp @@ -334,6 +334,24 @@ SDValue AVRTargetLowering::LowerShifts(SDValue Op, SelectionDAG &DAG) const { llvm_unreachable("Invalid shift opcode"); } + // Optimize int8 shifts. + if (VT.getSizeInBits() == 8) { + if (Op.getOpcode() == ISD::SHL && 4 <= ShiftAmount && ShiftAmount < 7) { + // Optimize LSL when 4 <= ShiftAmount <= 6. + Victim = DAG.getNode(AVRISD::SWAP, dl, VT, Victim); + Victim = + DAG.getNode(ISD::AND, dl, VT, Victim, DAG.getConstant(0xf0, dl, VT)); + ShiftAmount -= 4; + } else if (Op.getOpcode() == ISD::SRL && 4 <= ShiftAmount && + ShiftAmount < 7) { + // Optimize LSR when 4 <= ShiftAmount <= 6. + Victim = DAG.getNode(AVRISD::SWAP, dl, VT, Victim); + Victim = + DAG.getNode(ISD::AND, dl, VT, Victim, DAG.getConstant(0x0f, dl, VT)); + ShiftAmount -= 4; + } + } + while (ShiftAmount--) { Victim = DAG.getNode(Opc8, dl, VT, Victim); } diff --git a/llvm/lib/Target/AVR/AVRISelLowering.h b/llvm/lib/Target/AVR/AVRISelLowering.h index d1eaf53b15e9..ed9aea7a3297 100644 --- a/llvm/lib/Target/AVR/AVRISelLowering.h +++ b/llvm/lib/Target/AVR/AVRISelLowering.h @@ -56,6 +56,8 @@ enum NodeType { CMPC, /// Test for zero or minus instruction. TST, + /// Swap Rd[7:4] <-> Rd[3:0]. + SWAP, /// Operand 0 and operand 1 are selection variable, operand 2 /// is condition code and operand 3 is flag operand. SELECT_CC diff --git a/llvm/lib/Target/AVR/AVRInstrInfo.td b/llvm/lib/Target/AVR/AVRInstrInfo.td index 8de85f6b36c5..926d1f853a37 100644 --- a/llvm/lib/Target/AVR/AVRInstrInfo.td +++ b/llvm/lib/Target/AVR/AVRInstrInfo.td @@ -67,6 +67,9 @@ def AVRrolLoop : SDNode<"AVRISD::ROLLOOP", SDTIntShiftOp>; def AVRrorLoop : SDNode<"AVRISD::RORLOOP", SDTIntShiftOp>; def AVRasrLoop : SDNode<"AVRISD::ASRLOOP", SDTIntShiftOp>; +// SWAP node. +def AVRSwap : SDNode<"AVRISD::SWAP", SDTIntUnaryOp>; + //===----------------------------------------------------------------------===// // AVR Operands, Complex Patterns and Transformations Definitions. //===----------------------------------------------------------------------===// @@ -1729,7 +1732,7 @@ def SWAPRd : FRd<0b1001, (outs GPR8:$rd), (ins GPR8:$src), "swap\t$rd", - [(set i8:$rd, (bswap i8:$src))]>; + [(set i8:$rd, (AVRSwap i8:$src))]>; // IO register bit set/clear operations. //:TODO: add patterns when popcount(imm)==2 to be expanded with 2 sbi/cbi diff --git a/llvm/test/CodeGen/AVR/ctlz.ll b/llvm/test/CodeGen/AVR/ctlz.ll index 8681b8a3f1f5..93c2f0bdfa41 100644 --- a/llvm/test/CodeGen/AVR/ctlz.ll +++ b/llvm/test/CodeGen/AVR/ctlz.ll @@ -10,8 +10,7 @@ declare i8 @llvm.ctlz.i8(i8) ; CHECK-LABEL: count_leading_zeros: ; CHECK: cpi [[RESULT:r[0-9]+]], 0 -; CHECK: brne .LBB0_1 -; CHECK: rjmp .LBB0_2 +; CHECK: breq .LBB0_2 ; CHECK: mov [[SCRATCH:r[0-9]+]], {{.*}}[[RESULT]] ; CHECK: lsr {{.*}}[[SCRATCH]] ; CHECK: or {{.*}}[[SCRATCH]], {{.*}}[[RESULT]] @@ -20,10 +19,8 @@ declare i8 @llvm.ctlz.i8(i8) ; CHECK: lsr {{.*}}[[RESULT]] ; CHECK: or {{.*}}[[RESULT]], {{.*}}[[SCRATCH]] ; CHECK: mov {{.*}}[[SCRATCH]], {{.*}}[[RESULT]] -; CHECK: lsr {{.*}}[[SCRATCH]] -; CHECK: lsr {{.*}}[[SCRATCH]] -; CHECK: lsr {{.*}}[[SCRATCH]] -; CHECK: lsr {{.*}}[[SCRATCH]] +; CHECK: swap {{.*}}[[SCRATCH]] +; CHECK: andi {{.*}}[[SCRATCH]], 15 ; CHECK: or {{.*}}[[SCRATCH]], {{.*}}[[RESULT]] ; CHECK: com {{.*}}[[SCRATCH]] ; CHECK: mov {{.*}}[[RESULT]], {{.*}}[[SCRATCH]] @@ -37,10 +34,7 @@ declare i8 @llvm.ctlz.i8(i8) ; CHECK: andi {{.*}}[[SCRATCH]], 51 ; CHECK: add {{.*}}[[SCRATCH]], {{.*}}[[RESULT]] ; CHECK: mov {{.*}}[[RESULT]], {{.*}}[[SCRATCH]] -; CHECK: lsr {{.*}}[[RESULT]] -; CHECK: lsr {{.*}}[[RESULT]] -; CHECK: lsr {{.*}}[[RESULT]] -; CHECK: lsr {{.*}}[[RESULT]] +; CHECK: swap {{.*}}[[RESULT]] ; CHECK: add {{.*}}[[RESULT]], {{.*}}[[SCRATCH]] ; CHECK: andi {{.*}}[[RESULT]], 15 ; CHECK: ret diff --git a/llvm/test/CodeGen/AVR/ctpop.ll b/llvm/test/CodeGen/AVR/ctpop.ll index 3c0c71ed1e3f..a2be891acbd8 100644 --- a/llvm/test/CodeGen/AVR/ctpop.ll +++ b/llvm/test/CodeGen/AVR/ctpop.ll @@ -20,10 +20,7 @@ declare i8 @llvm.ctpop.i8(i8) ; CHECK: andi {{.*}}[[RESULT]], 51 ; CHECK: add {{.*}}[[RESULT]], {{.*}}[[SCRATCH]] ; CHECK: mov {{.*}}[[SCRATCH]], {{.*}}[[RESULT]] -; CHECK: lsr {{.*}}[[SCRATCH]] -; CHECK: lsr {{.*}}[[SCRATCH]] -; CHECK: lsr {{.*}}[[SCRATCH]] -; CHECK: lsr {{.*}}[[SCRATCH]] +; CHECK: swap {{.*}}[[SCRATCH]] ; CHECK: add {{.*}}[[SCRATCH]], {{.*}}[[RESULT]] ; CHECK: andi {{.*}}[[SCRATCH]], 15 ; CHECK: mov {{.*}}[[RESULT]], {{.*}}[[SCRATCH]] diff --git a/llvm/test/CodeGen/AVR/cttz.ll b/llvm/test/CodeGen/AVR/cttz.ll index 60ba57edcab7..b68994f3ab1d 100644 --- a/llvm/test/CodeGen/AVR/cttz.ll +++ b/llvm/test/CodeGen/AVR/cttz.ll @@ -26,10 +26,7 @@ declare i8 @llvm.cttz.i8(i8) ; CHECK: andi {{.*}}[[RESULT]], 51 ; CHECK: add {{.*}}[[RESULT]], {{.*}}[[SCRATCH]] ; CHECK: mov {{.*}}[[SCRATCH]], {{.*}}[[RESULT]] -; CHECK: lsr {{.*}}[[SCRATCH]] -; CHECK: lsr {{.*}}[[SCRATCH]] -; CHECK: lsr {{.*}}[[SCRATCH]] -; CHECK: lsr {{.*}}[[SCRATCH]] +; CHECK: swap {{.*}}[[SCRATCH]] ; CHECK: add {{.*}}[[SCRATCH]], {{.*}}[[RESULT]] ; CHECK: andi {{.*}}[[SCRATCH]], 15 ; CHECK: mov {{.*}}[[RESULT]], {{.*}}[[SCRATCH]] diff --git a/llvm/test/CodeGen/AVR/shift.ll b/llvm/test/CodeGen/AVR/shift.ll index 42ca766d3729..e5d3aeea5878 100644 --- a/llvm/test/CodeGen/AVR/shift.ll +++ b/llvm/test/CodeGen/AVR/shift.ll @@ -50,3 +50,105 @@ define i64 @shift_i64_i64(i64 %a, i64 %b) { %result = shl i64 %a, %b ret i64 %result } + +define i8 @lsl_i8_1(i8 %a) { +; CHECK-LABEL: lsl_i8_1: +; CHECK: lsl r24 + %res = shl i8 %a, 1 + ret i8 %res +} + +define i8 @lsl_i8_2(i8 %a) { +; CHECK-LABEL: lsl_i8_2: +; CHECK: lsl r24 +; CHECK-NEXT: lsl r24 + %res = shl i8 %a, 2 + ret i8 %res +} + +define i8 @lsl_i8_3(i8 %a) { +; CHECK-LABEL: lsl_i8_3: +; CHECK: lsl r24 +; CHECK-NEXT: lsl r24 +; CHECK-NEXT: lsl r24 + %res = shl i8 %a, 3 + ret i8 %res +} + +define i8 @lsl_i8_4(i8 %a) { +; CHECK-LABEL: lsl_i8_4: +; CHECK: swap r24 +; CHECK-NEXT: andi r24, -16 + %res = shl i8 %a, 4 + ret i8 %res +} + +define i8 @lsl_i8_5(i8 %a) { +; CHECK-LABEL: lsl_i8_5: +; CHECK: swap r24 +; CHECK-NEXT: andi r24, -16 +; CHECK-NEXT: lsl r24 + %res = shl i8 %a, 5 + ret i8 %res +} + +define i8 @lsl_i8_6(i8 %a) { +; CHECK-LABEL: lsl_i8_6: +; CHECK: swap r24 +; CHECK-NEXT: andi r24, -16 +; CHECK-NEXT: lsl r24 +; CHECK-NEXT: lsl r24 + %res = shl i8 %a, 6 + ret i8 %res +} + +define i8 @lsr_i8_1(i8 %a) { +; CHECK-LABEL: lsr_i8_1: +; CHECK: lsr r24 + %res = lshr i8 %a, 1 + ret i8 %res +} + +define i8 @lsr_i8_2(i8 %a) { +; CHECK-LABEL: lsr_i8_2: +; CHECK: lsr r24 +; CHECK-NEXT: lsr r24 + %res = lshr i8 %a, 2 + ret i8 %res +} + +define i8 @lsr_i8_3(i8 %a) { +; CHECK-LABEL: lsr_i8_3: +; CHECK: lsr r24 +; CHECK-NEXT: lsr r24 +; CHECK-NEXT: lsr r24 + %res = lshr i8 %a, 3 + ret i8 %res +} + +define i8 @lsr_i8_4(i8 %a) { +; CHECK-LABEL: lsr_i8_4: +; CHECK: swap r24 +; CHECK-NEXT: andi r24, 15 + %res = lshr i8 %a, 4 + ret i8 %res +} + +define i8 @lsr_i8_5(i8 %a) { +; CHECK-LABEL: lsr_i8_5: +; CHECK: swap r24 +; CHECK-NEXT: andi r24, 15 +; CHECK-NEXT: lsr r24 + %res = lshr i8 %a, 5 + ret i8 %res +} + +define i8 @lsr_i8_6(i8 %a) { +; CHECK-LABEL: lsr_i8_6: +; CHECK: swap r24 +; CHECK-NEXT: andi r24, 15 +; CHECK-NEXT: lsr r24 +; CHECK-NEXT: lsr r24 + %res = lshr i8 %a, 6 + ret i8 %res +} _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits