match(Op0, m_Xor(m_Value(Y), m_SignMask())))
return Y;
+ // add nuw %x, -1 -> -1, because %x can only be 0.
+ if (isNUW && match(Op1, m_AllOnes()))
+ return Op1; // Which is -1.
+
/// i1 add -> xor.
if (MaxRecurse && Op0->getType()->isIntOrIntVectorTy(1))
if (Value *V = SimplifyXorInst(Op0, Op1, Q, MaxRecurse-1))
define i32 @shl_add_nuw(i32 %NBits) {
; CHECK-LABEL: @shl_add_nuw(
-; CHECK-NEXT: ret i32 0
+; CHECK-NEXT: ret i32 -1
;
%setbit = shl i32 1, %NBits
%ret = add nuw i32 %setbit, -1
define i32 @shl_add_nsw_nuw(i32 %NBits) {
; CHECK-LABEL: @shl_add_nsw_nuw(
-; CHECK-NEXT: ret i32 0
+; CHECK-NEXT: ret i32 -1
;
%setbit = shl i32 1, %NBits
%ret = add nuw nsw i32 %setbit, -1
define i32 @shl_nsw_add_nuw(i32 %NBits) {
; CHECK-LABEL: @shl_nsw_add_nuw(
-; CHECK-NEXT: ret i32 0
+; CHECK-NEXT: ret i32 -1
;
%setbit = shl nsw i32 1, %NBits
%ret = add nuw i32 %setbit, -1
define i32 @shl_nsw_add_nsw_nuw(i32 %NBits) {
; CHECK-LABEL: @shl_nsw_add_nsw_nuw(
-; CHECK-NEXT: ret i32 0
+; CHECK-NEXT: ret i32 -1
;
%setbit = shl nsw i32 1, %NBits
%ret = add nuw nsw i32 %setbit, -1
define i32 @shl_nuw_add_nuw(i32 %NBits) {
; CHECK-LABEL: @shl_nuw_add_nuw(
-; CHECK-NEXT: ret i32 0
+; CHECK-NEXT: ret i32 -1
;
%setbit = shl nuw i32 1, %NBits
%ret = add nuw i32 %setbit, -1
define i32 @shl_nuw_add_nsw_nuw(i32 %NBits) {
; CHECK-LABEL: @shl_nuw_add_nsw_nuw(
-; CHECK-NEXT: ret i32 0
+; CHECK-NEXT: ret i32 -1
;
%setbit = shl nuw i32 1, %NBits
%ret = add nuw nsw i32 %setbit, -1
define i32 @shl_nsw_nuw_add_nuw(i32 %NBits) {
; CHECK-LABEL: @shl_nsw_nuw_add_nuw(
-; CHECK-NEXT: ret i32 0
+; CHECK-NEXT: ret i32 -1
;
%setbit = shl nuw nsw i32 1, %NBits
%ret = add nuw i32 %setbit, -1
define i32 @shl_nsw_nuw_add_nsw_nuw(i32 %NBits) {
; CHECK-LABEL: @shl_nsw_nuw_add_nsw_nuw(
-; CHECK-NEXT: ret i32 0
+; CHECK-NEXT: ret i32 -1
;
%setbit = shl nuw nsw i32 1, %NBits
%ret = add nuw nsw i32 %setbit, -1
define i8 @add_nuw (i8 %x) {
; CHECK-LABEL: @add_nuw(
-; CHECK-NEXT: [[RET:%.*]] = add nuw i8 [[X:%.*]], -1
-; CHECK-NEXT: ret i8 [[RET]]
+; CHECK-NEXT: ret i8 -1
;
%ret = add nuw i8 %x, -1
; nuw here means that %x can only be 0
define i8 @add_nuw_nsw (i8 %x) {
; CHECK-LABEL: @add_nuw_nsw(
-; CHECK-NEXT: [[RET:%.*]] = add nuw nsw i8 [[X:%.*]], -1
-; CHECK-NEXT: ret i8 [[RET]]
+; CHECK-NEXT: ret i8 -1
;
%ret = add nuw nsw i8 %x, -1
; nuw here means that %x can only be 0
define i8 @add_nuw_commute (i8 %x) {
; CHECK-LABEL: @add_nuw_commute(
-; CHECK-NEXT: [[RET:%.*]] = add nuw i8 -1, [[X:%.*]]
-; CHECK-NEXT: ret i8 [[RET]]
+; CHECK-NEXT: ret i8 -1
;
%ret = add nuw i8 -1, %x ; swapped
; nuw here means that %x can only be 0
define <2 x i8> @add_vec(<2 x i8> %x) {
; CHECK-LABEL: @add_vec(
-; CHECK-NEXT: [[RET:%.*]] = add nuw <2 x i8> [[X:%.*]], <i8 -1, i8 -1>
-; CHECK-NEXT: ret <2 x i8> [[RET]]
+; CHECK-NEXT: ret <2 x i8> <i8 -1, i8 -1>
;
%ret = add nuw <2 x i8> %x, <i8 -1, i8 -1>
ret <2 x i8> %ret
define <3 x i8> @add_vec_undef(<3 x i8> %x) {
; CHECK-LABEL: @add_vec_undef(
-; CHECK-NEXT: [[RET:%.*]] = add nuw <3 x i8> [[X:%.*]], <i8 -1, i8 undef, i8 -1>
-; CHECK-NEXT: ret <3 x i8> [[RET]]
+; CHECK-NEXT: ret <3 x i8> <i8 -1, i8 undef, i8 -1>
;
%ret = add nuw <3 x i8> %x, <i8 -1, i8 undef, i8 -1>
ret <3 x i8> %ret