[PATCH] D14803: [AArch64] Fix a corner case in BitFeild select
Geoff Berry via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 20 12:26:24 PST 2015
gberry added inline comments.
================
Comment at: lib/Target/AArch64/AArch64ISelDAGToDAG.cpp:2070
@@ -2065,3 +2069,3 @@
// In that case, we can eliminate the AND
Dst = OrOpd1->getOperand(0);
else
----------------
weimingz wrote:
> HI Geoff,
>
> The NumberOfIgnoredHighBits is used here to check if we can remove the AND.
> The current function
> static bool isBitfieldInsertOpFromOr(SDNode *N, unsigned &Opc, SDValue &Dst,
> SDValue &Src, unsigned &ImmR,
> unsigned &ImmS, SelectionDAG *CurDAG)
> always expects a BFM op if it returns true.
>
> I tried putting code like
> if (NumberOfIgnoredHighBits == 32) {
> Src = Dst;
> }
> But it doest make much difference.
> mov w8, w0
> bfi w8, w8, #8, #24
> mov w9, w0
> bfi w9, w8, #8, #24
> mov w8, w0
> bfi w8, w9, #8, #24
> bfi w0, w8, #8, #24
> lsl w0, w0, #8
>
>
I was thinking something more like the following diff, which will eliminate a mov and a bfi from the final code. It seems like if we're already computing the bit-liveness of the 'Or' we should take advantage of it. I'd like to hear someone else's opinion on whether it is worth the effort (since we clearly haven't seen many cases that would hit this or they would have crashed).
@@ -1974,7 +1974,8 @@ static bool isBitfieldPositioningOp(SelectionDAG *CurDAG, SDValue Op,
// f = Opc Opd0, Opd1, LSB, MSB ; where Opc is a BFM, LSB = imm, and MSB = imm2
static bool isBitfieldInsertOpFromOr(SDNode *N, unsigned &Opc, SDValue &Dst,
SDValue &Src, unsigned &ImmR,
- unsigned &ImmS, SelectionDAG *CurDAG) {
+ unsigned &ImmS, SelectionDAG *CurDAG,
+ const APInt &UsefulBits) {
assert(N->getOpcode() == ISD::OR && "Expect a OR operation");
// Set Opc
@@ -1988,9 +1989,6 @@ static bool isBitfieldInsertOpFromOr(SDNode *N, unsigned &Opc, SDValue &Dst,
// Because of simplify-demanded-bits in DAGCombine, involved masks may not
// have the expected shape. Try to undo that.
- APInt UsefulBits;
- getUsefulBits(SDValue(N, 0), UsefulBits);
-
unsigned NumberOfIgnoredLowBits = UsefulBits.countTrailingZeros();
unsigned NumberOfIgnoredHighBits = UsefulBits.countLeadingZeros();
@@ -2083,11 +2081,17 @@ SDNode *AArch64DAGToDAGISel::SelectBitfieldInsertOp(SDNode *N) {
unsigned Opc;
unsigned LSB, MSB;
SDValue Opd0, Opd1;
+ EVT VT = N->getValueType(0);
- if (!isBitfieldInsertOpFromOr(N, Opc, Opd0, Opd1, LSB, MSB, CurDAG))
+ APInt NUsefulBits;
+ getUsefulBits(SDValue(N, 0), NUsefulBits);
+ if (!NUsefulBits)
+ return CurDAG->SelectNodeTo(N, TargetOpcode::IMPLICIT_DEF, VT);
+
+ if (!isBitfieldInsertOpFromOr(N, Opc, Opd0, Opd1, LSB, MSB, CurDAG,
+ NUsefulBits))
return nullptr;
- EVT VT = N->getValueType(0);
SDLoc dl(N);
SDValue Ops[] = { Opd0,
Opd1,
================
Comment at: test/CodeGen/AArch64/bitfield-pr25571.ll:4
@@ +3,3 @@
+target datalayout = "e-m:e-i64:64-i128:128-n8:16:32:64-S128"
+target triple = "aarch64--linux-gnu"
+
----------------
You can get rid of the datalayout and triple lines (just pass the triple via a -mtriple= command line flag on the run line). You may also want to consider adding this test to another pre-existing test file (perhaps bitfield-insert.ll?).
================
Comment at: test/CodeGen/AArch64/bitfield-pr25571.ll:7
@@ +6,3 @@
+define i32 @test(i8 %a, i32 %b) {
+; CHECK-LABEL: test
+; CHECK: bfi
----------------
Add a ':' after test to avoid false matches.
================
Comment at: test/CodeGen/AArch64/bitfield-pr25571.ll:11
@@ +10,3 @@
+; CHECK: bfi
+; CHECK: bfi
+ %conv = zext i8 %a to i32 ; 0 0 0 0 A
----------------
Maybe check for an lsl at the end as well?
================
Comment at: test/CodeGen/AArch64/bitfield-pr25571.ll:12
@@ +11,3 @@
+; CHECK: bfi
+ %conv = zext i8 %a to i32 ; 0 0 0 0 A
+ %shl = shl i32 %b, 8 ; B2 B1 B0 0
----------------
This comment should be: 0 0 0 A
http://reviews.llvm.org/D14803
More information about the llvm-commits
mailing list