Index: llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp =================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -74,11 +74,12 @@ // b) (x & (~(-1 << MaskShAmt))) << ShiftShAmt // c) (x & (-1 >> MaskShAmt)) << ShiftShAmt // d) (x & ((-1 << MaskShAmt) >> MaskShAmt)) << ShiftShAmt +// e) ((x << MaskShAmt) l>> MaskShAmt) << ShiftShAmt // All these patterns can be simplified to just: // x << ShiftShAmt // iff: -// a,b) (MaskShAmt+ShiftShAmt) u>= bitwidth(x) -// c,d) (ShiftShAmt-MaskShAmt) s>= 0 (i.e. ShiftShAmt u>= MaskShAmt) +// a,b) (MaskShAmt+ShiftShAmt) u>= bitwidth(x) +// c,d,e) (ShiftShAmt-MaskShAmt) s>= 0 (i.e. ShiftShAmt u>= MaskShAmt) static Instruction * dropRedundantMaskingOfLeftShiftInput(BinaryOperator *OuterShift, const SimplifyQuery &SQ) { @@ -115,7 +116,9 @@ APInt(BitWidth, BitWidth)))) return nullptr; // All good, we can do this fold. - } else if (match(Masked, m_c_And(m_CombineOr(MaskC, MaskD), m_Value(X)))) { + } else if (match(Masked, m_c_And(m_CombineOr(MaskC, MaskD), m_Value(X))) || + match(Masked, m_LShr(m_Shl(m_Value(X), m_Value(MaskShAmt)), + m_Deferred(MaskShAmt)))) { // Can we simplify (ShiftShAmt-MaskShAmt) ? Value *ShAmtsDiff = SimplifySubInst(ShiftShAmt, MaskShAmt, /*IsNSW=*/false, /*IsNUW=*/false, Index: llvm/trunk/test/Transforms/InstCombine/redundant-left-shift-input-masking-variant-e.ll =================================================================== --- llvm/trunk/test/Transforms/InstCombine/redundant-left-shift-input-masking-variant-e.ll +++ llvm/trunk/test/Transforms/InstCombine/redundant-left-shift-input-masking-variant-e.ll @@ -21,7 +21,7 @@ ; CHECK-NEXT: [[T1:%.*]] = lshr i32 [[T0]], [[NBITS]] ; CHECK-NEXT: call void @use32(i32 [[T0]]) ; CHECK-NEXT: call void @use32(i32 [[T1]]) -; CHECK-NEXT: [[T2:%.*]] = shl i32 [[T1]], [[NBITS]] +; CHECK-NEXT: [[T2:%.*]] = shl i32 [[X]], [[NBITS]] ; CHECK-NEXT: ret i32 [[T2]] ; %t0 = shl i32 %x, %nbits @@ -40,7 +40,7 @@ ; CHECK-NEXT: call void @use32(i32 [[T0]]) ; CHECK-NEXT: call void @use32(i32 [[T1]]) ; CHECK-NEXT: call void @use32(i32 [[T2]]) -; CHECK-NEXT: [[T3:%.*]] = shl i32 [[T1]], [[T2]] +; CHECK-NEXT: [[T3:%.*]] = shl i32 [[X]], [[T2]] ; CHECK-NEXT: ret i32 [[T3]] ; %t0 = shl i32 %x, %nbits @@ -65,7 +65,7 @@ ; CHECK-NEXT: call void @use3xi32(<3 x i32> [[T0]]) ; CHECK-NEXT: call void @use3xi32(<3 x i32> [[T1]]) ; CHECK-NEXT: call void @use3xi32(<3 x i32> [[T2]]) -; CHECK-NEXT: [[T3:%.*]] = shl <3 x i32> [[T1]], [[T2]] +; CHECK-NEXT: [[T3:%.*]] = shl <3 x i32> [[X]], [[T2]] ; CHECK-NEXT: ret <3 x i32> [[T3]] ; %t0 = shl <3 x i32> %x, %nbits @@ -86,7 +86,7 @@ ; CHECK-NEXT: call void @use3xi32(<3 x i32> [[T0]]) ; CHECK-NEXT: call void @use3xi32(<3 x i32> [[T1]]) ; CHECK-NEXT: call void @use3xi32(<3 x i32> [[T2]]) -; CHECK-NEXT: [[T3:%.*]] = shl <3 x i32> [[T1]], [[T2]] +; CHECK-NEXT: [[T3:%.*]] = shl <3 x i32> [[X]], [[T2]] ; CHECK-NEXT: ret <3 x i32> [[T3]] ; %t0 = shl <3 x i32> %x, %nbits @@ -107,7 +107,7 @@ ; CHECK-NEXT: call void @use3xi32(<3 x i32> [[T0]]) ; CHECK-NEXT: call void @use3xi32(<3 x i32> [[T1]]) ; CHECK-NEXT: call void @use3xi32(<3 x i32> [[T2]]) -; CHECK-NEXT: [[T3:%.*]] = shl <3 x i32> [[T1]], [[T2]] +; CHECK-NEXT: [[T3:%.*]] = shl <3 x i32> [[X]], [[T2]] ; CHECK-NEXT: ret <3 x i32> [[T3]] ; %t0 = shl <3 x i32> %x, %nbits @@ -128,7 +128,7 @@ ; CHECK-NEXT: [[T1:%.*]] = lshr i32 [[T0]], [[NBITS]] ; CHECK-NEXT: call void @use32(i32 [[T0]]) ; CHECK-NEXT: call void @use32(i32 [[T1]]) -; CHECK-NEXT: [[T2:%.*]] = shl nuw i32 [[T1]], [[NBITS]] +; CHECK-NEXT: [[T2:%.*]] = shl i32 [[X]], [[NBITS]] ; CHECK-NEXT: ret i32 [[T2]] ; %t0 = shl i32 %x, %nbits @@ -145,7 +145,7 @@ ; CHECK-NEXT: [[T1:%.*]] = lshr i32 [[T0]], [[NBITS]] ; CHECK-NEXT: call void @use32(i32 [[T0]]) ; CHECK-NEXT: call void @use32(i32 [[T1]]) -; CHECK-NEXT: [[T2:%.*]] = shl nsw i32 [[T1]], [[NBITS]] +; CHECK-NEXT: [[T2:%.*]] = shl i32 [[X]], [[NBITS]] ; CHECK-NEXT: ret i32 [[T2]] ; %t0 = shl i32 %x, %nbits @@ -162,7 +162,7 @@ ; CHECK-NEXT: [[T1:%.*]] = lshr i32 [[T0]], [[NBITS]] ; CHECK-NEXT: call void @use32(i32 [[T0]]) ; CHECK-NEXT: call void @use32(i32 [[T1]]) -; CHECK-NEXT: [[T2:%.*]] = shl nuw nsw i32 [[T1]], [[NBITS]] +; CHECK-NEXT: [[T2:%.*]] = shl i32 [[X]], [[NBITS]] ; CHECK-NEXT: ret i32 [[T2]] ; %t0 = shl i32 %x, %nbits