[llvm] r269226 - [AArch64] Improve getUsefulBitsForUse for narrow stores.
Chad Rosier via llvm-commits
llvm-commits at lists.llvm.org
Wed May 11 13:19:55 PDT 2016
Author: mcrosier
Date: Wed May 11 15:19:54 2016
New Revision: 269226
URL: http://llvm.org/viewvc/llvm-project?rev=269226&view=rev
Log:
[AArch64] Improve getUsefulBitsForUse for narrow stores.
For narrow stores (e.g., strb, srth) 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.
Differential Revision: http://reviews.llvm.org/D20175
Modified:
llvm/trunk/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
llvm/trunk/test/CodeGen/AArch64/bitfield-insert.ll
Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp?rev=269226&r1=269225&r2=269226&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp Wed May 11 15:19:54 2016
@@ -1849,6 +1849,20 @@ static void getUsefulBitsForUse(SDNode *
case AArch64::BFMWri:
case AArch64::BFMXri:
return getUsefulBitsFromBFM(SDValue(UserNode, 0), Orig, UsefulBits, Depth);
+
+ case AArch64::STRBui:
+ case AArch64::STRBBui:
+ if (UserNode->getOperand(0) != Orig)
+ return;
+ UsefulBits &= APInt(UsefulBits.getBitWidth(), 0xff);
+ return;
+
+ case AArch64::STRHui:
+ case AArch64::STRHHui:
+ if (UserNode->getOperand(0) != Orig)
+ return;
+ UsefulBits &= APInt(UsefulBits.getBitWidth(), 0xffff);
+ return;
}
}
Modified: llvm/trunk/test/CodeGen/AArch64/bitfield-insert.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/bitfield-insert.ll?rev=269226&r1=269225&r2=269226&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/bitfield-insert.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/bitfield-insert.ll Wed May 11 15:19:54 2016
@@ -237,3 +237,39 @@ define i32 @test_nouseful_bits(i8 %a, i3
%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
+}
More information about the llvm-commits
mailing list