[llvm] r346968 - [InstCombine] fix rotate narrowing bug for non-pow-2 types

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 15 09:19:14 PST 2018


Author: spatel
Date: Thu Nov 15 09:19:14 2018
New Revision: 346968

URL: http://llvm.org/viewvc/llvm-project?rev=346968&view=rev
Log:
[InstCombine] fix rotate narrowing bug for non-pow-2 types

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp
    llvm/trunk/test/Transforms/InstCombine/rotate.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp?rev=346968&r1=346967&r2=346968&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Thu Nov 15 09:19:14 2018
@@ -498,6 +498,13 @@ Instruction *InstCombiner::narrowRotate(
           shouldChangeType(Trunc.getSrcTy(), Trunc.getType())) &&
          "Don't narrow to an illegal scalar type");
 
+  // Bail out on strange types. It is possible to handle some of these patterns
+  // even with non-power-of-2 sizes, but it is not a likely scenario.
+  Type *DestTy = Trunc.getType();
+  unsigned NarrowWidth = DestTy->getScalarSizeInBits();
+  if (!isPowerOf2_32(NarrowWidth))
+    return nullptr;
+
   // First, find an or'd pair of opposite shifts with the same shifted operand:
   // trunc (or (lshr ShVal, ShAmt0), (shl ShVal, ShAmt1))
   Value *Or0, *Or1;
@@ -538,8 +545,6 @@ Instruction *InstCombiner::narrowRotate(
     return nullptr;
   };
 
-  Type *DestTy = Trunc.getType();
-  unsigned NarrowWidth = DestTy->getScalarSizeInBits();
   Value *ShAmt = matchShiftAmount(ShAmt0, ShAmt1, NarrowWidth);
   bool SubIsOnLHS = false;
   if (!ShAmt) {

Modified: llvm/trunk/test/Transforms/InstCombine/rotate.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/rotate.ll?rev=346968&r1=346967&r2=346968&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/rotate.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/rotate.ll Thu Nov 15 09:19:14 2018
@@ -123,17 +123,16 @@ define i8 @rotate8_not_safe(i8 %v, i32 %
   ret i8 %ret
 }
 
-; FIXME: A non-power-of-2 destination type can't be masked as above.
+; A non-power-of-2 destination type can't be masked as above.
 
 define i9 @rotate9_not_safe(i9 %v, i32 %shamt) {
 ; CHECK-LABEL: @rotate9_not_safe(
-; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[SHAMT:%.*]] to i9
-; CHECK-NEXT:    [[TMP2:%.*]] = sub i9 0, [[TMP1]]
-; CHECK-NEXT:    [[TMP3:%.*]] = and i9 [[TMP1]], 8
-; CHECK-NEXT:    [[TMP4:%.*]] = and i9 [[TMP2]], 8
-; CHECK-NEXT:    [[TMP5:%.*]] = lshr i9 [[V:%.*]], [[TMP4]]
-; CHECK-NEXT:    [[TMP6:%.*]] = shl i9 [[V]], [[TMP3]]
-; CHECK-NEXT:    [[RET:%.*]] = or i9 [[TMP5]], [[TMP6]]
+; CHECK-NEXT:    [[CONV:%.*]] = zext i9 [[V:%.*]] to i32
+; CHECK-NEXT:    [[SUB:%.*]] = sub i32 9, [[SHAMT:%.*]]
+; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[CONV]], [[SUB]]
+; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[CONV]], [[SHAMT]]
+; CHECK-NEXT:    [[OR:%.*]] = or i32 [[SHR]], [[SHL]]
+; CHECK-NEXT:    [[RET:%.*]] = trunc i32 [[OR]] to i9
 ; CHECK-NEXT:    ret i9 [[RET]]
 ;
   %conv = zext i9 %v to i32
@@ -331,17 +330,18 @@ define i8 @rotateleft_8_neg_mask_wide_am
   ret i8 %ret
 }
 
-; Non-power-of-2 types. This is transformed correctly, but it's not a typical rotate pattern. 
+; Non-power-of-2 types. This could be transformed, but it's not a typical rotate pattern.
 
 define i9 @rotateleft_9_neg_mask_wide_amount_commute(i9 %v, i33 %shamt) {
 ; CHECK-LABEL: @rotateleft_9_neg_mask_wide_amount_commute(
-; CHECK-NEXT:    [[TMP1:%.*]] = trunc i33 [[SHAMT:%.*]] to i9
-; CHECK-NEXT:    [[TMP2:%.*]] = sub i9 0, [[TMP1]]
-; CHECK-NEXT:    [[TMP3:%.*]] = and i9 [[TMP1]], 8
-; CHECK-NEXT:    [[TMP4:%.*]] = and i9 [[TMP2]], 8
-; CHECK-NEXT:    [[TMP5:%.*]] = shl i9 [[V:%.*]], [[TMP3]]
-; CHECK-NEXT:    [[TMP6:%.*]] = lshr i9 [[V]], [[TMP4]]
-; CHECK-NEXT:    [[RET:%.*]] = or i9 [[TMP5]], [[TMP6]]
+; CHECK-NEXT:    [[NEG:%.*]] = sub i33 0, [[SHAMT:%.*]]
+; CHECK-NEXT:    [[LSHAMT:%.*]] = and i33 [[SHAMT]], 8
+; CHECK-NEXT:    [[RSHAMT:%.*]] = and i33 [[NEG]], 8
+; CHECK-NEXT:    [[CONV:%.*]] = zext i9 [[V:%.*]] to i33
+; CHECK-NEXT:    [[SHL:%.*]] = shl i33 [[CONV]], [[LSHAMT]]
+; CHECK-NEXT:    [[SHR:%.*]] = lshr i33 [[CONV]], [[RSHAMT]]
+; CHECK-NEXT:    [[OR:%.*]] = or i33 [[SHL]], [[SHR]]
+; CHECK-NEXT:    [[RET:%.*]] = trunc i33 [[OR]] to i9
 ; CHECK-NEXT:    ret i9 [[RET]]
 ;
   %neg = sub i33 0, %shamt




More information about the llvm-commits mailing list