diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | 9 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/rotate.ll | 32 | 
2 files changed, 23 insertions, 18 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index a934e0aa68e..582f69fb2d2 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -498,6 +498,13 @@ Instruction *InstCombiner::narrowRotate(TruncInst &Trunc) {            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(TruncInst &Trunc) {      return nullptr;    }; -  Type *DestTy = Trunc.getType(); -  unsigned NarrowWidth = DestTy->getScalarSizeInBits();    Value *ShAmt = matchShiftAmount(ShAmt0, ShAmt1, NarrowWidth);    bool SubIsOnLHS = false;    if (!ShAmt) { diff --git a/llvm/test/Transforms/InstCombine/rotate.ll b/llvm/test/Transforms/InstCombine/rotate.ll index 00b0d808f1c..c5b03fc2800 100644 --- a/llvm/test/Transforms/InstCombine/rotate.ll +++ b/llvm/test/Transforms/InstCombine/rotate.ll @@ -123,17 +123,16 @@ define i8 @rotate8_not_safe(i8 %v, i32 %shamt) {    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_amount_commute(i8 %v, i32 %shamt) {    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  | 

