GlobalISel: Check for powers of 2 for inverse funnel shift lowering
authorMatt Arsenault <Matthew.Arsenault@amd.com>
Mon, 29 Mar 2021 21:26:49 +0000 (17:26 -0400)
committerMatt Arsenault <Matthew.Arsenault@amd.com>
Tue, 20 Apr 2021 15:30:22 +0000 (11:30 -0400)
This doesn't make a practical difference since it would only be broken
if a target actually had a legal non-power-of-2 inverse shift.

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

index 99b6ea8..0ab80de 100644 (file)
@@ -5392,6 +5392,10 @@ LegalizerHelper::lowerFunnelShiftWithInverse(MachineInstr &MI) {
   LLT ShTy = MRI.getType(Z);
 
   unsigned BW = Ty.getScalarSizeInBits();
+
+  if (!isPowerOf2_32(BW))
+    return UnableToLegalize;
+
   const bool IsFSHL = MI.getOpcode() == TargetOpcode::G_FSHL;
   unsigned RevOpcode = IsFSHL ? TargetOpcode::G_FSHR : TargetOpcode::G_FSHL;
 
@@ -5490,9 +5494,16 @@ LegalizerHelper::lowerFunnelShift(MachineInstr &MI) {
 
   bool IsFSHL = MI.getOpcode() == TargetOpcode::G_FSHL;
   unsigned RevOpcode = IsFSHL ? TargetOpcode::G_FSHR : TargetOpcode::G_FSHL;
+
+  // TODO: Use smarter heuristic that accounts for vector legalization.
   if (LI.getAction({RevOpcode, {Ty, ShTy}}).Action == Lower)
     return lowerFunnelShiftAsShifts(MI);
-  return lowerFunnelShiftWithInverse(MI);
+
+  // This only works for powers of 2, fallback to shifts if it fails.
+  LegalizerHelper::LegalizeResult Result = lowerFunnelShiftWithInverse(MI);
+  if (Result == UnableToLegalize)
+    return lowerFunnelShiftAsShifts(MI);
+  return Result;
 }
 
 LegalizerHelper::LegalizeResult