diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 186697d3d02..e3a11cd27e1 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -2780,7 +2780,7 @@ SDValue SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDValue LegalOp, SDValue SelectionDAGLegalize::ExpandBITREVERSE(SDValue Op, SDLoc dl) { EVT VT = Op.getValueType(); EVT SHVT = TLI.getShiftAmountTy(VT, DAG.getDataLayout()); - unsigned Sz = VT.getSizeInBits(); + unsigned Sz = VT.getScalarSizeInBits(); SDValue Tmp, Tmp2; Tmp = DAG.getConstant(0, dl, VT); @@ -2791,8 +2791,10 @@ SDValue SelectionDAGLegalize::ExpandBITREVERSE(SDValue Op, SDLoc dl) { else Tmp2 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(I - J, dl, SHVT)); - Tmp2 = - DAG.getNode(ISD::AND, dl, VT, Tmp2, DAG.getConstant(1U << J, dl, VT)); + + APInt Shift(Sz, 1); + Shift = Shift.shl(J); + Tmp2 = DAG.getNode(ISD::AND, dl, VT, Tmp2, DAG.getConstant(Shift, dl, VT)); Tmp = DAG.getNode(ISD::OR, dl, VT, Tmp, Tmp2); } diff --git a/test/CodeGen/AArch64/bitreverse.ll b/test/CodeGen/AArch64/bitreverse.ll index b780412f765..702581789bb 100644 --- a/test/CodeGen/AArch64/bitreverse.ll +++ b/test/CodeGen/AArch64/bitreverse.ll @@ -21,3 +21,48 @@ define i8 @g(i8 %a) { %b = call i8 @llvm.bitreverse.i8(i8 %a) ret i8 %b } + +declare <8 x i8> @llvm.bitreverse.v8i8(<8 x i8>) readnone + +define <8 x i8> @g_vec(<8 x i8> %a) { +; Try and match as much of the sequence as precisely as possible. + +; CHECK-LABEL: g_vec: +; CHECK-DAG: movi [[M1:v.*]], #0x80 +; CHECK-DAG: movi [[M2:v.*]], #0x40 +; CHECK-DAG: movi [[M3:v.*]], #0x20 +; CHECK-DAG: movi [[M4:v.*]], #0x10 +; CHECK-DAG: movi [[M5:v.*]], #0x8 +; CHECK-DAG: movi [[M6:v.*]], #0x4{{$}} +; CHECK-DAG: movi [[M7:v.*]], #0x2{{$}} +; CHECK-DAG: movi [[M8:v.*]], #0x1{{$}} +; CHECK-DAG: shl [[S1:v.*]], v0.8b, #7 +; CHECK-DAG: shl [[S2:v.*]], v0.8b, #5 +; CHECK-DAG: shl [[S3:v.*]], v0.8b, #3 +; CHECK-DAG: shl [[S4:v.*]], v0.8b, #1 +; CHECK-DAG: ushr [[S5:v.*]], v0.8b, #1 +; CHECK-DAG: ushr [[S6:v.*]], v0.8b, #3 +; CHECK-DAG: ushr [[S7:v.*]], v0.8b, #5 +; CHECK-DAG: ushr [[S8:v.*]], v0.8b, #7 +; CHECK-DAG: and [[A1:v.*]], [[S1]], [[M1]] +; CHECK-DAG: and [[A2:v.*]], [[S2]], [[M2]] +; CHECK-DAG: and [[A3:v.*]], [[S3]], [[M3]] +; CHECK-DAG: and [[A4:v.*]], [[S4]], [[M4]] +; CHECK-DAG: and [[A5:v.*]], [[S5]], [[M5]] +; CHECK-DAG: and [[A6:v.*]], [[S6]], [[M6]] +; CHECK-DAG: and [[A7:v.*]], [[S7]], [[M7]] +; CHECK-DAG: and [[A8:v.*]], [[S8]], [[M8]] + +; The rest can be ORRed together in any order; it's not worth the test +; maintenance to match them precisely. +; CHECK-DAG: orr +; CHECK-DAG: orr +; CHECK-DAG: orr +; CHECK-DAG: orr +; CHECK-DAG: orr +; CHECK-DAG: orr +; CHECK-DAG: orr +; CHECK: ret + %b = call <8 x i8> @llvm.bitreverse.v8i8(<8 x i8> %a) + ret <8 x i8> %b +}