[ARM] Prefer BIC over BFC in ARM mode.

BIC is generally faster, and it can put the output in a different
register from the input.

We already do this in Thumb2 mode; not sure why the equivalent fix
never got applied to ARM mode.

Differential Revision: https://reviews.llvm.org/D31797

llvm-svn: 299803
This commit is contained in:
Eli Friedman 2017-04-07 22:01:23 +00:00
parent eb80a51b52
commit 75631c97ba
8 changed files with 26 additions and 19 deletions

View File

@ -3893,6 +3893,7 @@ def MVNi : AsI1<0b1111, (outs GPR:$Rd), (ins mod_imm:$imm), DPFrm,
let Inst{11-0} = imm;
}
let AddedComplexity = 1 in
def : ARMPat<(and GPR:$src, mod_imm_not:$imm),
(BICri GPR:$src, mod_imm_not:$imm)>;

View File

@ -19,7 +19,7 @@ entry:
call void @llvm.va_start(i8* %g1)
; CHECK: add [[REG:(r[0-9]+)|(lr)]], {{(r[0-9]+)|(lr)}}, #7
; CHECK: bfc [[REG]], #0, #3
; CHECK: bic [[REG]], [[REG]], #7
%0 = va_arg i8** %g, double
call void @llvm.va_end(i8* %g1)

View File

@ -77,7 +77,7 @@ entry:
define i32 @f7(i32 %x, i32 %y) {
; CHECK-LABEL: f7:
; CHECK: bfi r1, r0, #4, #1
; CHECK: bfi r0, r2, #4, #1
%y2 = and i32 %y, 4294967040 ; 0xFFFFFF00
%and = and i32 %x, 4
%or = or i32 %y2, 16
@ -88,8 +88,8 @@ define i32 @f7(i32 %x, i32 %y) {
define i32 @f8(i32 %x, i32 %y) {
; CHECK-LABEL: f8:
; CHECK: bfi r1, r0, #4, #1
; CHECK: bfi r1, r0, #5, #1
; CHECK: bfi r0, r2, #4, #1
; CHECK: bfi r0, r2, #5, #1
%y2 = and i32 %y, 4294967040 ; 0xFFFFFF00
%and = and i32 %x, 4
%or = or i32 %y2, 48
@ -111,7 +111,7 @@ define i32 @f9(i32 %x, i32 %y) {
define i32 @f10(i32 %x, i32 %y) {
; CHECK-LABEL: f10:
; CHECK: bfi r1, r0, #4, #2
; CHECK: bfi r0, r2, #4, #2
%y2 = and i32 %y, 4294967040 ; 0xFFFFFF00
%and = and i32 %x, 4
%or = or i32 %y2, 32
@ -128,7 +128,7 @@ define i32 @f10(i32 %x, i32 %y) {
define i32 @f11(i32 %x, i32 %y) {
; CHECK-LABEL: f11:
; CHECK: bfi r1, r0, #4, #3
; CHECK: bfi r0, r2, #4, #3
%y2 = and i32 %y, 4294967040 ; 0xFFFFFF00
%and = and i32 %x, 4
%or = or i32 %y2, 32
@ -150,7 +150,7 @@ define i32 @f11(i32 %x, i32 %y) {
define i32 @f12(i32 %x, i32 %y) {
; CHECK-LABEL: f12:
; CHECK: bfi r1, r0, #4, #1
; CHECK: bfi r0, r2, #4, #1
%y2 = and i32 %y, 4294967040 ; 0xFFFFFF00
%and = and i32 %x, 4
%or = or i32 %y2, 16

View File

@ -1,17 +1,24 @@
; RUN: llc -mtriple=arm-eabi %s -o - | FileCheck %s
define i32 @f1(i32 %a, i32 %b) {
; CHECK-LABEL: f1:
; CHECK: bic r0, r0, r1
%tmp = xor i32 %b, 4294967295
%tmp1 = and i32 %a, %tmp
ret i32 %tmp1
}
; CHECK: bic r0, r0, r1
define i32 @f2(i32 %a, i32 %b) {
; CHECK-LABEL: f2:
; CHECK: bic r0, r0, r1
%tmp = xor i32 %b, 4294967295
%tmp1 = and i32 %tmp, %a
ret i32 %tmp1
}
; CHECK: bic r0, r0, r1
define i32 @f3(i32 %a) {
; CHECK-LABEL: f3:
; CHECK: bic r0, r0, #255
%tmp = and i32 %a, -256
ret i32 %tmp
}

View File

@ -597,7 +597,7 @@ define void @test_fma(half* %p, half* %q, half* %r) #0 {
; CHECK-FP16: vcvtb.f16.f32
; CHECK-LIBCALL-LABEL: test_fabs:
; CHECK-LIBCALL: bl __aeabi_h2f
; CHECK-LIBCALL: bfc
; CHECK-LIBCALL: bic
; CHECK-LIBCALL: bl __aeabi_f2h
define void @test_fabs(half* %p) {
%a = load half, half* %p, align 2
@ -687,7 +687,7 @@ define void @test_maxnan(half* %p) #0 {
; CHECK-LIBCALL: bl __aeabi_h2f
; CHECK-LIBCALL: bl __aeabi_h2f
; CHECK-VFP-LIBCALL: vbsl
; CHECK-NOVFP: bfc
; CHECK-NOVFP: bic
; CHECK-NOVFP: and
; CHECK-NOVFP: orr
; CHECK-LIBCALL: bl __aeabi_f2h

View File

@ -35,7 +35,7 @@ entry:
; CHECK-NOT: vldr
; CHECK: ldrd [[REG1:(r[0-9]+)]], [[REG2:(r[0-9]+)]], [r0]
; CHECK-NOT: b LBB
; CHECK: bfc [[REG2]], #31, #1
; CHECK: bic [[REG2]], [[REG2]], #-2147483648
; CHECK: cmp [[REG1]], #0
; CHECK: cmpeq [[REG2]], #0
; CHECK-NOT: vcmp.f32

View File

@ -14,8 +14,7 @@ define double @f(double %a) {
define float @g(float %a) {
; CHECK-LABEL: g:
; CHECK-THUMB: bic r0, r0, #-2147483648
; CHECK-ARM: bfc r0, #31, #1
; CHECK: bic r0, r0, #-2147483648
; CHECK-NEXT: bx lr
%x = call float @llvm.fabs.f32(float %a) readnone
ret float %x

View File

@ -4,8 +4,8 @@
; CHECK-LABEL: test1:
; CHECK-NOT: bfc
; CHECK: add [[REG:(r[0-9]+)|(lr)]], {{(r[0-9]+)|(lr)}}, #7
; CHECK: bfc [[REG]], #0, #3
; CHECK-NOT: bfc
; CHECK: bic {{(r[0-9]+)|(lr)}}, [[REG]], #7
; CHECK-NOT: bic
define i64 @test1(i32 %i, ...) nounwind optsize {
entry:
@ -20,8 +20,8 @@ entry:
; CHECK-LABEL: test2:
; CHECK-NOT: bfc
; CHECK: add [[REG:(r[0-9]+)|(lr)]], {{(r[0-9]+)|(lr)}}, #7
; CHECK: bfc [[REG]], #0, #3
; CHECK-NOT: bfc
; CHECK: bic {{(r[0-9]+)|(lr)}}, [[REG]], #7
; CHECK-NOT: bic
; CHECK: bx lr
define double @test2(i32 %a, i32* %b, ...) nounwind optsize {