These expansions were rather inefficient and were done with more code than necessary. This change optimizes them to use expansions more similar to GCC. The code size is the same (when optimizing for code size) but somehow LLVM reorders blocks in a non-optimal way. Still, this should be an improvement with a reduction in code size of around 0.12% (when building compiler-rt). Differential Revision: https://reviews.llvm.org/D86418
60 lines
1.0 KiB
LLVM
60 lines
1.0 KiB
LLVM
; RUN: llc < %s -march=avr | FileCheck %s
|
|
|
|
; Bit rotation tests.
|
|
|
|
; CHECK-LABEL: rol8:
|
|
define i8 @rol8(i8 %val, i8 %amt) {
|
|
; CHECK: andi r22, 7
|
|
|
|
; CHECK-NEXT: dec r22
|
|
; CHECK-NEXT: brmi .LBB0_2
|
|
|
|
; CHECK-NEXT: .LBB0_1:
|
|
; CHECK-NEXT: lsl r24
|
|
; CHECK-NEXT: adc r24, r1
|
|
; CHECK-NEXT: dec r22
|
|
; CHECK-NEXT: brpl .LBB0_1
|
|
|
|
; CHECK-NEXT: .LBB0_2:
|
|
; CHECK-NEXT: ret
|
|
%mod = urem i8 %amt, 8
|
|
|
|
%inv = sub i8 8, %mod
|
|
%parta = shl i8 %val, %mod
|
|
%partb = lshr i8 %val, %inv
|
|
|
|
%rotl = or i8 %parta, %partb
|
|
|
|
ret i8 %rotl
|
|
}
|
|
|
|
|
|
; CHECK-LABEL: ror8:
|
|
define i8 @ror8(i8 %val, i8 %amt) {
|
|
; CHECK: andi r22, 7
|
|
|
|
; CHECK-NEXT: dec r22
|
|
; CHECK-NEXT: brmi .LBB1_2
|
|
|
|
; CHECK-NEXT: .LBB1_1:
|
|
; CHECK-NEXT: lsr r24
|
|
; CHECK-NEXT: ldi r0, 0
|
|
; CHECK-NEXT: ror r0
|
|
; CHECK-NEXT: or r24, r0
|
|
; CHECK-NEXT: dec r22
|
|
; CHECK-NEXT: brpl .LBB1_1
|
|
|
|
; CHECK-NEXT: .LBB1_2:
|
|
; CHECK-NEXT: ret
|
|
%mod = urem i8 %amt, 8
|
|
|
|
%inv = sub i8 8, %mod
|
|
%parta = lshr i8 %val, %mod
|
|
%partb = shl i8 %val, %inv
|
|
|
|
%rotr = or i8 %parta, %partb
|
|
|
|
ret i8 %rotr
|
|
}
|
|
|