[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