[globalisel] Add a G_BSWAP instruction and support bswap using it.
authorDaniel Sanders <daniel_l_sanders@apple.com>
Tue, 19 Sep 2017 14:25:15 +0000 (14:25 +0000)
committerDaniel Sanders <daniel_l_sanders@apple.com>
Tue, 19 Sep 2017 14:25:15 +0000 (14:25 +0000)
llvm-svn: 313633

llvm/include/llvm/Target/GenericOpcodes.td
llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
llvm/include/llvm/Target/TargetOpcodes.def
llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp
llvm/test/CodeGen/AArch64/GlobalISel/select-bswap.mir [new file with mode: 0644]

index aef088a..557c1dc 100644 (file)
@@ -118,6 +118,12 @@ def G_VAARG : Instruction {
   let mayStore = 1;
 }
 
+def G_BSWAP : Instruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type0:$src);
+  let hasSideEffects = 0;
+}
+
 //------------------------------------------------------------------------------
 // Binary ops.
 //------------------------------------------------------------------------------
index a770951..f6da58b 100644 (file)
@@ -70,6 +70,7 @@ def : GINodeEquiv<G_INTRINSIC, intrinsic_wo_chain>;
 def : GINodeEquiv<G_INTRINSIC_W_SIDE_EFFECTS, intrinsic_void>;
 def : GINodeEquiv<G_INTRINSIC_W_SIDE_EFFECTS, intrinsic_w_chain>;
 def : GINodeEquiv<G_BR, br>;
+def : GINodeEquiv<G_BSWAP, bswap>;
 
 // Specifies the GlobalISel equivalents for SelectionDAG's ComplexPattern.
 // Should be used on defs that subclass GIComplexOperandMatcher<>.
index 3ecb8b5..c2654be 100644 (file)
@@ -427,12 +427,15 @@ HANDLE_TARGET_OPCODE(G_EXTRACT_VECTOR_ELT)
 /// Generic shufflevector.
 HANDLE_TARGET_OPCODE(G_SHUFFLE_VECTOR)
 
+/// Generic byte swap.
+HANDLE_TARGET_OPCODE(G_BSWAP)
+
 // TODO: Add more generic opcodes as we move along.
 
 /// Marker for the end of the generic opcode.
 /// This is used to check if an opcode is in the range of the
 /// generic opcodes.
-HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_SHUFFLE_VECTOR)
+HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_BSWAP)
 
 /// BUILTIN_OP_END - This must be the last enum value in this list.
 /// The target-specific post-isel opcode values start here.
index e28e43a..380668d 100644 (file)
@@ -44,6 +44,9 @@ AArch64LegalizerInfo::AArch64LegalizerInfo() {
   for (auto Ty : {s1, s8})
     setAction({G_PHI, Ty}, WidenScalar);
 
+  for (auto Ty : { s32, s64 })
+    setAction({G_BSWAP, Ty}, Legal);
+
   for (unsigned BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR, G_SHL}) {
     // These operations naturally get the right answer when used on
     // GPR32, even if the actual type is narrower.
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-bswap.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-bswap.mir
new file mode 100644 (file)
index 0000000..56a964f
--- /dev/null
@@ -0,0 +1,60 @@
+# RUN: llc -mtriple=aarch64-- -run-pass=instruction-select -verify-machineinstrs -global-isel %s -o - | FileCheck %s
+
+--- |
+  target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+
+  define void @bswap_s32() { ret void }
+  define void @bswap_s64() { ret void }
+...
+
+---
+# CHECK-LABEL: name: bswap_s32
+name:            bswap_s32
+legalized:       true
+regBankSelected: true
+
+# CHECK:      registers:
+# CHECK-NEXT:  - { id: 0, class: gpr32, preferred-register: '' }
+# CHECK-NEXT:  - { id: 1, class: gpr32, preferred-register: '' }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+
+# CHECK:  body:
+# CHECK:    %0 = COPY %w0
+# CHECK:    %1 = REVWr %0
+# CHECK:    %w0 = COPY %1
+body:             |
+  bb.0:
+    liveins: %w0
+
+    %0(s32) = COPY %w0
+    %1(s32) = G_BSWAP %0
+    %w0 = COPY %1
+...
+
+---
+# CHECK-LABEL: name: bswap_s64
+name:            bswap_s64
+legalized:       true
+regBankSelected: true
+
+# CHECK:      registers:
+# CHECK-NEXT:  - { id: 0, class: gpr64, preferred-register: '' }
+# CHECK-NEXT:  - { id: 1, class: gpr64, preferred-register: '' }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+
+# CHECK:  body:
+# CHECK:    %0 = COPY %x0
+# CHECK:    %1 = REVXr %0
+# CHECK:    %x0 = COPY %1
+body:             |
+  bb.0:
+    liveins: %x0
+
+    %0(s64) = COPY %x0
+    %1(s64) = G_BSWAP %0
+    %x0 = COPY %1
+...