[llvm] r253023 - [SDAG] Fix expansion of BITREVERSE

James Molloy via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 13 02:03:33 PST 2015


Author: jamesm
Date: Fri Nov 13 04:02:36 2015
New Revision: 253023

URL: http://llvm.org/viewvc/llvm-project?rev=253023&view=rev
Log:
[SDAG] Fix expansion of BITREVERSE

Richard Trieu noted that UBSan detected an overflowing shift, and the obvious fix caused a crash.

What was happening was that the shiftee (1U) was indeed too small for the possible range of shifts it had to handle, but also we were using "VT.getSizeInBits()" to get the maximum type bitwidth, but we wanted "VT.getScalarSizeInBits()" to get the vector lane size instead of the entire vector size.

Use an APInt for the shift and VT.getScalarSizeInBits().

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
    llvm/trunk/test/CodeGen/AArch64/bitreverse.ll

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=253023&r1=253022&r2=253023&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Nov 13 04:02:36 2015
@@ -2780,7 +2780,7 @@ SDValue SelectionDAGLegalize::PromoteLeg
 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::ExpandBITR
     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);
   }
 

Modified: llvm/trunk/test/CodeGen/AArch64/bitreverse.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/bitreverse.ll?rev=253023&r1=253022&r2=253023&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/bitreverse.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/bitreverse.ll Fri Nov 13 04:02:36 2015
@@ -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
+}




More information about the llvm-commits mailing list