[PATCH] D20175: [AArch64] Improve getUsefulBitsForUse for narrow stores.

Chad Rosier via llvm-commits llvm-commits at lists.llvm.org
Wed May 11 10:23:18 PDT 2016


mcrosier created this revision.
mcrosier added reviewers: t.p.northover, jmolloy.
mcrosier added a subscriber: llvm-commits.
Herald added subscribers: rengolin, aemerson.

For narrow stores (i.e., ldrh, ldrh) we know the upper bits of the register are unused/not useful.  In some cases we can use this information to eliminate unnecessary instructions.

For example, without this patch we generate (from the 2nd test case):

  ldr w8, [x0]
  and w8, w8, #0xfff0
  bfxil w8, w2, #16, #4
  strh w8, [x1]

and after the patch the 'and' is removed:

  ldr             w8, [x0]
  bfxil   w8, w2, #16, #4
  strh            w8, [x1]
  ret

During the lowering of the bitfield insert instruction the 'and' is eliminated because we know the upper 16-bits that are masked off are unused and the lower 4-bits that are masked off are overwritten by the insert itself.  Therefore, the 'and' is unnecessary.

Please take a look,
 Chad

http://reviews.llvm.org/D20175

Files:
  lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
  test/CodeGen/AArch64/bitfield-insert.ll

Index: test/CodeGen/AArch64/bitfield-insert.ll
===================================================================
--- test/CodeGen/AArch64/bitfield-insert.ll
+++ test/CodeGen/AArch64/bitfield-insert.ll
@@ -237,3 +237,39 @@
   %shl.4 = shl i32 %or.3, 8     ;   A A A 0
   ret i32 %shl.4
 }
+
+define void @test_nouseful_strb(i32* %ptr32, i8* %ptr8, i32 %x)  {
+entry:
+; CHECK-LABEL: @test_nouseful_strb
+; CHECK: ldr [[REG1:w[0-9]+]],
+; CHECK-NOT:  and {{w[0-9]+}}, {{w[0-9]+}}, #0xf8
+; CHECK-NEXT: bfxil [[REG1]], w2, #16, #3
+; CHECK-NEXT: strb [[REG1]],
+; CHECK-NEXT: ret
+  %0 = load i32, i32* %ptr32, align 8
+  %and = and i32 %0, -8
+  %shr = lshr i32 %x, 16
+  %and1 = and i32 %shr, 7
+  %or = or i32 %and, %and1
+  %trunc = trunc i32 %or to i8
+  store i8 %trunc, i8* %ptr8
+  ret void
+}
+
+define void @test_nouseful_strh(i32* %ptr32, i16* %ptr16, i32 %x)  {
+entry:
+; CHECK-LABEL: @test_nouseful_strh
+; CHECK: ldr [[REG1:w[0-9]+]],
+; CHECK-NOT:  and {{w[0-9]+}}, {{w[0-9]+}}, #0xfff0
+; CHECK-NEXT: bfxil [[REG1]], w2, #16, #4
+; CHECK-NEXT: strh [[REG1]],
+; CHECK-NEXT: ret
+  %0 = load i32, i32* %ptr32, align 8
+  %and = and i32 %0, -16
+  %shr = lshr i32 %x, 16
+  %and1 = and i32 %shr, 15
+  %or = or i32 %and, %and1
+  %trunc = trunc i32 %or to i16
+  store i16 %trunc, i16* %ptr16
+  ret void
+}
Index: lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
===================================================================
--- lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
+++ lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
@@ -1849,6 +1849,16 @@
   case AArch64::BFMWri:
   case AArch64::BFMXri:
     return getUsefulBitsFromBFM(SDValue(UserNode, 0), Orig, UsefulBits, Depth);
+
+  case AArch64::STRBui:
+  case AArch64::STRBBui:
+    UsefulBits &= APInt(UsefulBits.getBitWidth(), 0xff);
+    return;
+
+  case AArch64::STRHui:
+  case AArch64::STRHHui:
+    UsefulBits &= APInt(UsefulBits.getBitWidth(), 0xffff);
+    return;
   }
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D20175.56934.patch
Type: text/x-patch
Size: 1948 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160511/64af4cbc/attachment.bin>


More information about the llvm-commits mailing list