Index: llvm/test/Transforms/InstCombine/addsub-constant-folding.ll =================================================================== --- llvm/test/Transforms/InstCombine/addsub-constant-folding.ll +++ llvm/test/Transforms/InstCombine/addsub-constant-folding.ll @@ -132,6 +132,113 @@ ret i32 %t1 } +define i8 @add_nsw_const_const_sub_nsw(i8 %arg) { +; CHECK-LABEL: @add_nsw_const_const_sub_nsw( +; CHECK-NEXT: [[T1:%.*]] = sub i8 -128, [[ARG:%.*]] +; CHECK-NEXT: ret i8 [[T1]] +; + %t0 = add nsw i8 %arg, 1 + %t1 = sub nsw i8 -127, %t0 + ret i8 %t1 +} + +define i8 @add_nsw_const_const_sub(i8 %arg) { +; CHECK-LABEL: @add_nsw_const_const_sub( +; CHECK-NEXT: [[T1:%.*]] = sub i8 -128, [[ARG:%.*]] +; CHECK-NEXT: ret i8 [[T1]] +; + %t0 = add nsw i8 %arg, 1 + %t1 = sub i8 -127, %t0 + ret i8 %t1 +} + +define i8 @add_const_const_sub_nsw(i8 %arg) { +; CHECK-LABEL: @add_const_const_sub_nsw( +; CHECK-NEXT: [[T1:%.*]] = sub i8 -128, [[ARG:%.*]] +; CHECK-NEXT: ret i8 [[T1]] +; + %t0 = add i8 %arg, 1 + %t1 = sub nsw i8 -127, %t0 + ret i8 %t1 +} + +; 127-X with nsw will be more poisonous than -127-(X+2) with nsw. (see X = -1) +define i8 @add_nsw_const_const_sub_nsw_ov(i8 %arg) { +; CHECK-LABEL: @add_nsw_const_const_sub_nsw_ov( +; CHECK-NEXT: [[T1:%.*]] = sub i8 127, [[ARG:%.*]] +; CHECK-NEXT: ret i8 [[T1]] +; + %t0 = add nsw i8 %arg, 2 + %t1 = sub nsw i8 -127, %t0 + ret i8 %t1 +} + +define i8 @add_nuw_const_const_sub_nuw(i8 %arg) { +; CHECK-LABEL: @add_nuw_const_const_sub_nuw( +; CHECK-NEXT: [[T1:%.*]] = sub i8 -128, [[ARG:%.*]] +; CHECK-NEXT: ret i8 [[T1]] +; + %t0 = add nuw i8 %arg, 1 + %t1 = sub nuw i8 -127, %t0 + ret i8 %t1 +} + +define i8 @add_const_const_sub_nuw(i8 %arg) { +; CHECK-LABEL: @add_const_const_sub_nuw( +; CHECK-NEXT: [[T1:%.*]] = sub i8 -128, [[ARG:%.*]] +; CHECK-NEXT: ret i8 [[T1]] +; + %t0 = add i8 %arg, 1 + %t1 = sub nuw i8 -127, %t0 + ret i8 %t1 +} + + +define <2 x i8> @non_splat_vec_add_nsw_const_const_sub_nsw_not_ov1(<2 x i8> %arg) { +; CHECK-LABEL: @non_splat_vec_add_nsw_const_const_sub_nsw_not_ov1( +; CHECK-NEXT: [[T1:%.*]] = sub <2 x i8> , [[ARG:%.*]] +; CHECK-NEXT: ret <2 x i8> [[T1]] +; + %t0 = add nsw <2 x i8> %arg, + %t1 = sub nsw <2 x i8> , %t0 + ret <2 x i8> %t1 +} + + +; TODO: We can add nsw on sub, curret Value Tracking use [max element,min element] constant range, to check overflow for vector? +define <2 x i8> @non_splat_vec_add_nsw_const_const_sub_nsw_not_ov2(<2 x i8> %arg) { +; CHECK-LABEL: @non_splat_vec_add_nsw_const_const_sub_nsw_not_ov2( +; CHECK-NEXT: [[T1:%.*]] = sub <2 x i8> , [[ARG:%.*]] +; CHECK-NEXT: ret <2 x i8> [[T1]] +; + %t0 = add nsw <2 x i8> %arg, + %t1 = sub nsw <2 x i8> , %t0 + ret <2 x i8> %t1 +} + +; TODO: We can add nsw on sub, curret Value Tracking can't decide this is not overflowed? +define <2 x i8> @non_splat_vec_add_nsw_const_const_sub_nsw_not_ov3(<2 x i8> %arg) { +; CHECK-LABEL: @non_splat_vec_add_nsw_const_const_sub_nsw_not_ov3( +; CHECK-NEXT: [[T1:%.*]] = sub <2 x i8> , [[ARG:%.*]] +; CHECK-NEXT: ret <2 x i8> [[T1]] +; + %t0 = add nsw <2 x i8> %arg, + %t1 = sub nsw <2 x i8> , %t0 + ret <2 x i8> %t1 +} + +; 127-X with nsw will be more poisonous than -127-(X+2) with nsw. (see X = -1) +define <2 x i8> @non_splat_vec_add_nsw_const_const_sub_nsw_ov(<2 x i8> %arg) { +; CHECK-LABEL: @non_splat_vec_add_nsw_const_const_sub_nsw_ov( +; CHECK-NEXT: [[T1:%.*]] = sub <2 x i8> , [[ARG:%.*]] +; CHECK-NEXT: ret <2 x i8> [[T1]] +; + %t0 = add nsw <2 x i8> %arg, + %t1 = sub nsw <2 x i8> , %t0 + ret <2 x i8> %t1 +} + + define i32 @add_const_const_sub_extrause(i32 %arg) { ; CHECK-LABEL: @add_const_const_sub_extrause( ; CHECK-NEXT: [[T0:%.*]] = add i32 [[ARG:%.*]], 8