return R;
// See if we can turn a signed shr into an unsigned shr.
- if (MaskedValueIsZero(Op0, APInt::getSignMask(BitWidth), 0, &I))
- return BinaryOperator::CreateLShr(Op0, Op1);
+ if (MaskedValueIsZero(Op0, APInt::getSignMask(BitWidth), 0, &I)) {
+ Instruction *Lshr = BinaryOperator::CreateLShr(Op0, Op1);
+ Lshr->setIsExact(I.isExact());
+ return Lshr;
+ }
// ashr (xor %x, -1), %y --> xor (ashr %x, %y), -1
if (match(Op0, m_OneUse(m_Not(m_Value(X))))) {
define i8 @ashr_known_pos_exact(i8 %x, i8 %y) {
; CHECK-LABEL: @ashr_known_pos_exact(
; CHECK-NEXT: [[P:%.*]] = and i8 [[X:%.*]], 127
-; CHECK-NEXT: [[R:%.*]] = lshr i8 [[P]], [[Y:%.*]]
+; CHECK-NEXT: [[R:%.*]] = lshr exact i8 [[P]], [[Y:%.*]]
; CHECK-NEXT: ret i8 [[R]]
;
%p = and i8 %x, 127
define <2 x i8> @ashr_known_pos_exact_vec(<2 x i8> %x, <2 x i8> %y) {
; CHECK-LABEL: @ashr_known_pos_exact_vec(
; CHECK-NEXT: [[P:%.*]] = mul nsw <2 x i8> [[X:%.*]], [[X]]
-; CHECK-NEXT: [[R:%.*]] = lshr <2 x i8> [[P]], [[Y:%.*]]
+; CHECK-NEXT: [[R:%.*]] = lshr exact <2 x i8> [[P]], [[Y:%.*]]
; CHECK-NEXT: ret <2 x i8> [[R]]
;
%p = mul nsw <2 x i8> %x, %x
define <2 x i8> @ashr_constant_op0_not_undef_lane(i8 %x) {
; CHECK-LABEL: @ashr_constant_op0_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i8> poison, i8 [[X:%.*]], i64 1
-; CHECK-NEXT: [[BO:%.*]] = lshr <2 x i8> <i8 5, i8 2>, [[INS]]
+; CHECK-NEXT: [[BO:%.*]] = lshr exact <2 x i8> <i8 5, i8 2>, [[INS]]
; CHECK-NEXT: ret <2 x i8> [[BO]]
;
%ins = insertelement <2 x i8> poison, i8 %x, i32 1
define <2 x i8> @ashr_constant_op0_not_undef_lane(i8 %x) {
; CHECK-LABEL: @ashr_constant_op0_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i8> undef, i8 [[X:%.*]], i64 1
-; CHECK-NEXT: [[BO:%.*]] = lshr <2 x i8> <i8 5, i8 2>, [[INS]]
+; CHECK-NEXT: [[BO:%.*]] = lshr exact <2 x i8> <i8 5, i8 2>, [[INS]]
; CHECK-NEXT: ret <2 x i8> [[BO]]
;
%ins = insertelement <2 x i8> undef, i8 %x, i32 1