[GlobalISel][AArch64] Select llvm.bswap* for non-vector types

This teaches the IRTranslator to emit G_BSWAP when it runs into
Intrinsic::bswap. This allows us to select G_BSWAP for non-vector types in
AArch64.

Add a select-bswap.mir test, and add global isel checks to a couple existing
tests in test/CodeGen/AArch64.

This doesn't handle every bswap case, since some of these rely on known bits
stuff. This just lets us handle the naive case.

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@353861 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/GlobalISel/IRTranslator.cpp b/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 9b94a99..dd4e0df 100644
--- a/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -794,6 +794,8 @@
   switch (ID) {
     default:
       break;
+    case Intrinsic::bswap:
+      return TargetOpcode::G_BSWAP;
     case Intrinsic::ceil:
       return TargetOpcode::G_FCEIL;
     case Intrinsic::cos:
diff --git a/lib/Target/AArch64/select-bswap.mir b/lib/Target/AArch64/select-bswap.mir
new file mode 100644
index 0000000..13dfa99
--- /dev/null
+++ b/lib/Target/AArch64/select-bswap.mir
@@ -0,0 +1,38 @@
+# RUN: llc -verify-machineinstrs -mtriple aarch64--- \
+# RUN: -run-pass=instruction-select -mattr=+fullfp16 -global-isel %s -o - \
+# RUN: | FileCheck %s
+...
+---
+name:            bswap_s32
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    ; CHECK-LABEL: name:            bswap_s32
+    ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
+    ; CHECK: [[REVWr:%[0-9]+]]:gpr32 = REVWr [[COPY]]
+    ; CHECK: $w0 = COPY [[REVWr]]
+    liveins: $s0
+    %0:gpr(s32) = COPY $w0
+    %1:gpr(s32) = G_BSWAP %0
+    $w0 = COPY %1(s32)
+
+...
+---
+name:            bswap_s64
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    ; CHECK-LABEL: name:            bswap_s64
+    ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0
+    ; CHECK: [[REVXr:%[0-9]+]]:gpr64 = REVXr [[COPY]]
+    ; CHECK: $x0 = COPY [[REVXr]]
+    liveins: $x0
+    %0:gpr(s64) = COPY $d0
+    %1:gpr(s64) = G_BSWAP %0
+    $x0 = COPY %1(s64)
+
+...
diff --git a/test/CodeGen/AArch64/arm64-rev.ll b/test/CodeGen/AArch64/arm64-rev.ll
index 5a8d5b8..9b864c3 100644
--- a/test/CodeGen/AArch64/arm64-rev.ll
+++ b/test/CodeGen/AArch64/arm64-rev.ll
@@ -1,21 +1,32 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc < %s -mtriple=aarch64-eabi -aarch64-neon-syntax=apple | FileCheck %s
+; RUN: llc < %s -global-isel -global-isel-abort=2 -pass-remarks-missed=gisel* -mtriple=aarch64-eabi -aarch64-neon-syntax=apple | FileCheck %s --check-prefixes=FALLBACK,GISEL
 
+; FALLBACK-NOT: remark{{.*}}test_rev_w
 define i32 @test_rev_w(i32 %a) nounwind {
 ; CHECK-LABEL: test_rev_w:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    rev w0, w0
 ; CHECK-NEXT:    ret
+; GISEL-LABEL: test_rev_w:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    rev w0, w0
+; GISEL-NEXT:    ret
 entry:
   %0 = tail call i32 @llvm.bswap.i32(i32 %a)
   ret i32 %0
 }
 
+; FALLBACK-NOT: remark{{.*}}test_rev_x
 define i64 @test_rev_x(i64 %a) nounwind {
 ; CHECK-LABEL: test_rev_x:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    rev x0, x0
 ; CHECK-NEXT:    ret
+; GISEL-LABEL: test_rev_x:
+; GISEL:       // %bb.0: // %entry
+; GISEL-NEXT:    rev x0, x0
+; GISEL-NEXT:    ret
 entry:
   %0 = tail call i64 @llvm.bswap.i64(i64 %a)
   ret i64 %0
diff --git a/test/CodeGen/AArch64/dp1.ll b/test/CodeGen/AArch64/dp1.ll
index 4247afa..3250027 100644
--- a/test/CodeGen/AArch64/dp1.ll
+++ b/test/CodeGen/AArch64/dp1.ll
@@ -1,22 +1,29 @@
 ; RUN: llc -verify-machineinstrs -o - %s -mtriple=aarch64-linux-gnu | FileCheck %s
+; RUN: llc -global-isel -global-isel-abort=2 -pass-remarks-missed=gisel* -verify-machineinstrs -o - %s -mtriple=aarch64-linux-gnu | FileCheck %s --check-prefixes=FALLBACK,GISEL
 
 @var32 = global i32 0
 @var64 = global i64 0
 
+; FALLBACK-NOT: remark{{.*}}rev_i32
 define void @rev_i32() {
 ; CHECK-LABEL: rev_i32:
+; GISEL-LABEL: rev_i32:
     %val0_tmp = load i32, i32* @var32
     %val1_tmp = call i32 @llvm.bswap.i32(i32 %val0_tmp)
 ; CHECK: rev	{{w[0-9]+}}, {{w[0-9]+}}
+; GISEL: rev	{{w[0-9]+}}, {{w[0-9]+}}
     store volatile i32 %val1_tmp, i32* @var32
     ret void
 }
 
+; FALLBACK-NOT: remark{{.*}}rev_i64
 define void @rev_i64() {
 ; CHECK-LABEL: rev_i64:
+; GISEL-LABEL: rev_i64:
     %val0_tmp = load i64, i64* @var64
     %val1_tmp = call i64 @llvm.bswap.i64(i64 %val0_tmp)
 ; CHECK: rev	{{x[0-9]+}}, {{x[0-9]+}}
+; GISEL: rev	{{x[0-9]+}}, {{x[0-9]+}}
     store volatile i64 %val1_tmp, i64* @var64
     ret void
 }
@@ -149,4 +156,3 @@
 declare i64  @llvm.cttz.i64 (i64, i1)
 declare i32  @llvm.ctpop.i32 (i32)
 declare i64  @llvm.ctpop.i64 (i64)
-