The original shift is bigger, so this may qualify as 'obvious',
but here's an attempt at an Alive-based proof:
Name: exact
Pre: (C1 u< C2)
%a = shl i8 %x, C1
%b = lshr exact i8 %a, C2
=>
%c = lshr exact i8 %x, C2 - C1
%b = and i8 %c, ((1 << width(C1)) - 1) u>> C2
Optimization is correct!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293498
91177308-0d34-0410-b5e6-
96231b3b80d8
return NewLShr;
}
// (X << C1) >>u C2 --> (X >>u (C2 - C1)) & (-1 >> C2)
- Value *NewLShr = Builder->CreateLShr(X, ShiftDiff);
+ Value *NewLShr = Builder->CreateLShr(X, ShiftDiff, "", I.isExact());
APInt Mask(APInt::getLowBitsSet(BitWidth, BitWidth - ShAmt));
return BinaryOperator::CreateAnd(NewLShr, ConstantInt::get(Ty, Mask));
}
define i32 @test51_no_nuw(i32 %x) {
; CHECK-LABEL: @test51_no_nuw(
-; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 %x, 2
+; CHECK-NEXT: [[TMP1:%.*]] = lshr exact i32 %x, 2
; CHECK-NEXT: [[B:%.*]] = and i32 [[TMP1]], 536870911
; CHECK-NEXT: ret i32 [[B]]
;