diff --git a/llvm/test/Transforms/InstCombine/add.ll b/llvm/test/Transforms/InstCombine/add.ll index d84be9cd29d46..73e21d4370b7e 100644 --- a/llvm/test/Transforms/InstCombine/add.ll +++ b/llvm/test/Transforms/InstCombine/add.ll @@ -1,6 +1,9 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -passes=instcombine -S | FileCheck %s +declare void @use(i8) +declare void @use_i1(i1) + define i32 @select_0_or_1_from_bool(i1 %x) { ; CHECK-LABEL: @select_0_or_1_from_bool( ; CHECK-NEXT: [[NOT_X:%.*]] = xor i1 [[X:%.*]], true @@ -280,8 +283,6 @@ define i8 @reassoc_shl1_commute3(i8 %px, i8 %py) { ret i8 %r } -declare void @use(i8) - define i8 @reassoc_shl1_extra_use(i8 %x, i8 %y) { ; CHECK-LABEL: @reassoc_shl1_extra_use( ; CHECK-NEXT: [[A:%.*]] = add i8 [[Y:%.*]], [[X:%.*]] @@ -2729,3 +2730,129 @@ define i32 @floor_sdiv_wrong_op(i32 %x, i32 %y) { %r = add i32 %d, %s ret i32 %r } + +define i8 @signum_i8_i8(i8 %x) { +; CHECK-LABEL: @signum_i8_i8( +; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 0 +; CHECK-NEXT: [[ZGT0:%.*]] = zext i1 [[SGT0]] to i8 +; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X]], 7 +; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]] +; CHECK-NEXT: ret i8 [[R]] +; + %sgt0 = icmp sgt i8 %x, 0 + %zgt0 = zext i1 %sgt0 to i8 + %signbit = ashr i8 %x, 7 + %r = add i8 %zgt0, %signbit + ret i8 %r +} + +define i8 @signum_i8_i8_use1(i8 %x) { +; CHECK-LABEL: @signum_i8_i8_use1( +; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 0 +; CHECK-NEXT: [[ZGT0:%.*]] = zext i1 [[SGT0]] to i8 +; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X]], 7 +; CHECK-NEXT: call void @use(i8 [[SIGNBIT]]) +; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]] +; CHECK-NEXT: ret i8 [[R]] +; + %sgt0 = icmp sgt i8 %x, 0 + %zgt0 = zext i1 %sgt0 to i8 + %signbit = ashr i8 %x, 7 + call void @use(i8 %signbit) + %r = add i8 %zgt0, %signbit + ret i8 %r +} + +define i8 @signum_i8_i8_use2(i8 %x) { +; CHECK-LABEL: @signum_i8_i8_use2( +; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 0 +; CHECK-NEXT: [[ZGT0:%.*]] = zext i1 [[SGT0]] to i8 +; CHECK-NEXT: call void @use(i8 [[ZGT0]]) +; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X]], 7 +; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]] +; CHECK-NEXT: ret i8 [[R]] +; + %sgt0 = icmp sgt i8 %x, 0 + %zgt0 = zext i1 %sgt0 to i8 + call void @use(i8 %zgt0) + %signbit = ashr i8 %x, 7 + %r = add i8 %zgt0, %signbit + ret i8 %r +} + +define i8 @signum_i8_i8_use3(i8 %x) { +; CHECK-LABEL: @signum_i8_i8_use3( +; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 0 +; CHECK-NEXT: call void @use_i1(i1 [[SGT0]]) +; CHECK-NEXT: [[ZGT0:%.*]] = zext i1 [[SGT0]] to i8 +; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X]], 7 +; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]] +; CHECK-NEXT: ret i8 [[R]] +; + %sgt0 = icmp sgt i8 %x, 0 + call void @use_i1(i1 %sgt0) + %zgt0 = zext i1 %sgt0 to i8 + %signbit = ashr i8 %x, 7 + %r = add i8 %zgt0, %signbit + ret i8 %r +} + +define <2 x i5> @signum_v2i5_v2i5(<2 x i5> %x) { +; CHECK-LABEL: @signum_v2i5_v2i5( +; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt <2 x i5> [[X:%.*]], zeroinitializer +; CHECK-NEXT: [[ZGT0:%.*]] = zext <2 x i1> [[SGT0]] to <2 x i5> +; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr <2 x i5> [[X]], +; CHECK-NEXT: [[R:%.*]] = add <2 x i5> [[SIGNBIT]], [[ZGT0]] +; CHECK-NEXT: ret <2 x i5> [[R]] +; + %sgt0 = icmp sgt <2 x i5> %x, zeroinitializer + %zgt0 = zext <2 x i1> %sgt0 to <2 x i5> + %signbit = ashr <2 x i5> %x, + %r = add <2 x i5> %signbit, %zgt0 + ret <2 x i5> %r +} + +define i8 @signum_i8_i8_wrong_sh_amt(i8 %x) { +; CHECK-LABEL: @signum_i8_i8_wrong_sh_amt( +; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 0 +; CHECK-NEXT: [[ZGT0:%.*]] = zext i1 [[SGT0]] to i8 +; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X]], 6 +; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]] +; CHECK-NEXT: ret i8 [[R]] +; + %sgt0 = icmp sgt i8 %x, 0 + %zgt0 = zext i1 %sgt0 to i8 + %signbit = ashr i8 %x, 6 + %r = add i8 %zgt0, %signbit + ret i8 %r +} + +define i8 @signum_i8_i8_wrong_ext(i8 %x) { +; CHECK-LABEL: @signum_i8_i8_wrong_ext( +; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 0 +; CHECK-NEXT: [[ZGT0:%.*]] = sext i1 [[SGT0]] to i8 +; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X]], 7 +; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]] +; CHECK-NEXT: ret i8 [[R]] +; + %sgt0 = icmp sgt i8 %x, 0 + %zgt0 = sext i1 %sgt0 to i8 + %signbit = ashr i8 %x, 7 + %r = add i8 %zgt0, %signbit + ret i8 %r +} + +define i8 @signum_i8_i8_wrong_pred(i8 %x) { +; CHECK-LABEL: @signum_i8_i8_wrong_pred( +; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], -1 +; CHECK-NEXT: [[ZGT0:%.*]] = zext i1 [[SGT0]] to i8 +; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X]], 7 +; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]] +; CHECK-NEXT: ret i8 [[R]] +; + %sgt0 = icmp sge i8 %x, 0 + %zgt0 = zext i1 %sgt0 to i8 + %signbit = ashr i8 %x, 7 + %r = add i8 %zgt0, %signbit + ret i8 %r +}