| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 |
| ; RUN: opt < %s -passes=instcombine -S | FileCheck %s |
| |
| define i8 @add_and_sgt(i8 %x) { |
| ; CHECK-LABEL: define i8 @add_and_sgt( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[X]], i8 8) |
| ; CHECK-NEXT: [[S:%.*]] = add nuw nsw i8 [[TMP1]], 16 |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %add = add nsw i8 %x, 16 |
| %cmp = icmp sgt i8 %x, 8 |
| %s = select i1 %cmp, i8 %add, i8 24 |
| ret i8 %s |
| } |
| |
| define i8 @add_sgt_nuw(i8 %x) { |
| ; CHECK-LABEL: define i8 @add_sgt_nuw( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[X]], i8 8) |
| ; CHECK-NEXT: [[S:%.*]] = add nuw i8 [[TMP1]], 16 |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %add = add nuw i8 %x, 16 |
| %cmp = icmp sgt i8 %x, 8 |
| %s = select i1 %cmp, i8 %add, i8 24 |
| ret i8 %s |
| } |
| |
| define i8 @sub_and_ugt(i8 %x) { |
| ; CHECK-LABEL: define i8 @sub_and_ugt( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[X]], i8 100) |
| ; CHECK-NEXT: [[S:%.*]] = add nsw i8 [[TMP1]], -50 |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %sub = sub nsw i8 %x, 50 |
| %cmp = icmp ugt i8 %x, 100 |
| %s = select i1 %cmp, i8 50, i8 %sub |
| ret i8 %s |
| } |
| |
| define i8 @sub_ugt_nuw_nsw(i8 %x) { |
| ; CHECK-LABEL: define i8 @sub_ugt_nuw_nsw( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[X]], i8 100) |
| ; CHECK-NEXT: [[S:%.*]] = add nsw i8 [[TMP1]], -50 |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %sub = sub nuw nsw i8 %x, 50 |
| %cmp = icmp ugt i8 %x, 100 |
| %s = select i1 %cmp, i8 50, i8 %sub |
| ret i8 %s |
| } |
| |
| define i8 @mul_and_ult(i8 %x) { |
| ; CHECK-LABEL: define i8 @mul_and_ult( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[X]], i8 10) |
| ; CHECK-NEXT: [[S:%.*]] = mul nuw i8 [[TMP1]], 10 |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %add = mul nsw i8 %x, 10 |
| %cmp = icmp ult i8 10, %x |
| %s = select i1 %cmp, i8 100, i8 %add |
| ret i8 %s |
| } |
| |
| define i8 @mul_and_non_strict_predicate(i8 %x) { |
| ; CHECK-LABEL: define i8 @mul_and_non_strict_predicate( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[X]], i8 10) |
| ; CHECK-NEXT: [[S:%.*]] = mul i8 [[TMP1]], 10 |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %add = mul nsw i8 %x, 10 |
| %cmp = icmp sle i8 10, %x |
| %s = select i1 %cmp, i8 100, i8 %add |
| ret i8 %s |
| } |
| |
| define i8 @mul_ult_noflags(i8 %x) { |
| ; CHECK-LABEL: define i8 @mul_ult_noflags( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[X]], i8 10) |
| ; CHECK-NEXT: [[S:%.*]] = mul nuw i8 [[TMP1]], 10 |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %add = mul i8 %x, 10 |
| %cmp = icmp ult i8 10, %x |
| %s = select i1 %cmp, i8 100, i8 %add |
| ret i8 %s |
| } |
| |
| define i8 @udiv_and_slt(i8 %x) { |
| ; CHECK-LABEL: define i8 @udiv_and_slt( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[SUB:%.*]] = udiv i8 [[X]], 10 |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X]], 100 |
| ; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i8 10, i8 [[SUB]] |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %sub = udiv i8 %x, 10 |
| %cmp = icmp slt i8 %x, 100 |
| %s = select i1 %cmp, i8 10, i8 %sub |
| ret i8 %s |
| } |
| |
| define i8 @udiv_slt_exact(i8 %x) { |
| ; CHECK-LABEL: define i8 @udiv_slt_exact( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[SUB:%.*]] = udiv exact i8 [[X]], 10 |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X]], 100 |
| ; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i8 10, i8 [[SUB]] |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %sub = udiv exact i8 %x, 10 |
| %cmp = icmp slt i8 %x, 100 |
| %s = select i1 %cmp, i8 10, i8 %sub |
| ret i8 %s |
| } |
| |
| define i8 @canonicalize_icmp_operands(i8 %x) { |
| ; CHECK-LABEL: define i8 @canonicalize_icmp_operands( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[X]], i8 119) |
| ; CHECK-NEXT: [[S:%.*]] = add nsw i8 [[TMP1]], 8 |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %add = add nsw i8 %x, 8 |
| %cmp = icmp sle i8 120, %x |
| %s = select i1 %cmp, i8 127, i8 %add |
| ret i8 %s |
| } |
| |
| define i8 @flipped_strictness_predicate_and_constant(i8 %x, i8 %y) { |
| ; CHECK-LABEL: define i8 @flipped_strictness_predicate_and_constant( |
| ; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[X]], i8 1) |
| ; CHECK-NEXT: [[R:%.*]] = add i8 [[TMP1]], -2 |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %a = add i8 %x, -2 |
| %c = icmp ult i8 %x, 2 |
| %r = select i1 %c, i8 -1, i8 %a |
| ret i8 %r |
| } |
| |
| declare void @use(i1) |
| declare void @use_byte(i8) |
| |
| define i8 @multi_use_cond_and_sel(i8 %x) { |
| ; CHECK-LABEL: define i8 @multi_use_cond_and_sel( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X]], 8 |
| ; CHECK-NEXT: call void @use(i1 [[CMP]]) |
| ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[X]], i8 8) |
| ; CHECK-NEXT: [[S:%.*]] = add nuw nsw i8 [[TMP1]], 16 |
| ; CHECK-NEXT: call void @use_byte(i8 [[S]]) |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %add = add nsw i8 %x, 16 |
| %cmp = icmp sgt i8 %x, 8 |
| call void @use(i1 %cmp) |
| %s = select i1 %cmp, i8 %add, i8 24 |
| call void @use_byte(i8 %s) |
| ret i8 %s |
| } |
| |
| define void @rust_noop_loop() { |
| ; CHECK-LABEL: define void @rust_noop_loop() { |
| ; CHECK-NEXT: [[START:.*]]: |
| ; CHECK-NEXT: br label %[[BB2_I:.*]] |
| ; CHECK: [[BB2_I]]: |
| ; CHECK-NEXT: [[ITER_SROA_0_07:%.*]] = phi i32 [ 0, %[[START]] ], [ [[SPEC_SELECT5:%.*]], %[[BB2_I]] ] |
| ; CHECK-NEXT: [[_0_I3_I:%.*]] = icmp sgt i32 [[ITER_SROA_0_07]], 99 |
| ; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.smin.i32(i32 [[ITER_SROA_0_07]], i32 99) |
| ; CHECK-NEXT: [[SPEC_SELECT5]] = add nsw i32 [[TMP0]], 1 |
| ; CHECK-NEXT: br i1 [[_0_I3_I]], label %[[BASICBLOCK4:.*]], label %[[BB2_I]] |
| ; CHECK: [[BASICBLOCK4]]: |
| ; CHECK-NEXT: ret void |
| ; |
| start: |
| br label %bb2.i |
| |
| bb2.i: |
| %iter.sroa.0.07 = phi i32 [ 0, %start ], [ %spec.select5, %bb2.i ] |
| %_0.i3.i = icmp sgt i32 %iter.sroa.0.07, 99 |
| %0 = add nsw i32 %iter.sroa.0.07, 1 |
| %spec.select5 = select i1 %_0.i3.i, i32 100, i32 %0 |
| %_0.i.not.i = icmp sgt i32 %spec.select5, 100 |
| %or.cond = select i1 %_0.i3.i, i1 true, i1 %_0.i.not.i |
| br i1 %or.cond, label %basicblock4, label %bb2.i |
| |
| basicblock4: |
| ret void |
| } |
| |
| define <2 x i8> @add_non_splat_vector(<2 x i8> %x) { |
| ; CHECK-LABEL: define <2 x i8> @add_non_splat_vector( |
| ; CHECK-SAME: <2 x i8> [[X:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i8> @llvm.smax.v2i8(<2 x i8> [[X]], <2 x i8> <i8 0, i8 1>) |
| ; CHECK-NEXT: [[S:%.*]] = add nuw <2 x i8> [[TMP1]], <i8 1, i8 0> |
| ; CHECK-NEXT: ret <2 x i8> [[S]] |
| ; |
| %add = add <2 x i8> %x, <i8 1, i8 0> |
| %cmp = icmp sgt <2 x i8> %x, <i8 0, i8 1> |
| %s = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> <i8 1, i8 1> |
| ret <2 x i8> %s |
| } |
| |
| define <2 x i8> @or_splat_vector(<2 x i8> %x) { |
| ; CHECK-LABEL: define <2 x i8> @or_splat_vector( |
| ; CHECK-SAME: <2 x i8> [[X:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i8> @llvm.smax.v2i8(<2 x i8> [[X]], <2 x i8> splat (i8 1)) |
| ; CHECK-NEXT: [[S:%.*]] = or <2 x i8> [[TMP1]], splat (i8 1) |
| ; CHECK-NEXT: ret <2 x i8> [[S]] |
| ; |
| %add = or <2 x i8> %x, <i8 1, i8 1> |
| %cmp = icmp sgt <2 x i8> %x, <i8 0, i8 0> |
| %s = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> <i8 1, i8 1> |
| ret <2 x i8> %s |
| } |
| |
| define i8 @const_operands_dont_fold_negative(i8 %x) { |
| ; CHECK-LABEL: define i8 @const_operands_dont_fold_negative( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[X]], 16 |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X]], 18 |
| ; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i8 [[ADD]], i8 25 |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %add = add nsw i8 %x, 16 |
| %cmp = icmp sgt i8 %x, 18 |
| %s = select i1 %cmp, i8 %add, i8 25 |
| ret i8 %s |
| } |
| |
| define i8 @add_with_poison_negative(i8 %x) { |
| ; CHECK-LABEL: define i8 @add_with_poison_negative( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: ret i8 25 |
| ; |
| %add = add nsw i8 %x, poison |
| %cmp = icmp sgt i8 %x, 8 |
| %s = select i1 %cmp, i8 %add, i8 25 |
| ret i8 %s |
| } |
| |
| define i8 @add_with_overflow_negative(i8 %x) { |
| ; CHECK-LABEL: define i8 @add_with_overflow_negative( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 100 |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X]], 119 |
| ; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i8 -127, i8 [[ADD]] |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %add = add i8 %x, 100 |
| %cmp = icmp sle i8 120, %x |
| %s = select i1 %cmp, i8 -127, i8 %add |
| ret i8 %s |
| } |
| |
| define <2 x i8> @vector_with_poison_negative(<2 x i8> %x) { |
| ; CHECK-LABEL: define <2 x i8> @vector_with_poison_negative( |
| ; CHECK-SAME: <2 x i8> [[X:%.*]]) { |
| ; CHECK-NEXT: [[ADD:%.*]] = xor <2 x i8> [[X]], <i8 1, i8 poison> |
| ; CHECK-NEXT: [[CMP_INV:%.*]] = icmp slt <2 x i8> [[X]], splat (i8 1) |
| ; CHECK-NEXT: [[S:%.*]] = select <2 x i1> [[CMP_INV]], <2 x i8> splat (i8 1), <2 x i8> [[ADD]] |
| ; CHECK-NEXT: ret <2 x i8> [[S]] |
| ; |
| %add = xor <2 x i8> %x, <i8 1, i8 poison> |
| %cmp = icmp sgt <2 x i8> %x, <i8 0, i8 0> |
| %s = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> <i8 1, i8 1> |
| ret <2 x i8> %s |
| } |
| |
| define i8 @multi_use_bop_negative(i8 %x) { |
| ; CHECK-LABEL: define i8 @multi_use_bop_negative( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[X]], 16 |
| ; CHECK-NEXT: call void @use_byte(i8 [[ADD]]) |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X]], 7 |
| ; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i8 24, i8 [[ADD]] |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %add = add nsw i8 %x, 16 |
| call void @use_byte(i8 %add) |
| %cmp = icmp sle i8 8, %x |
| %s = select i1 %cmp, i8 24, i8 %add |
| ret i8 %s |
| } |
| |
| define half @float_negative(half %x) { |
| ; CHECK-LABEL: define half @float_negative( |
| ; CHECK-SAME: half [[X:%.*]]) { |
| ; CHECK-NEXT: [[ADD:%.*]] = fmul fast half [[X]], 0xH2E66 |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp ugt half [[X]], 0xH5640 |
| ; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], half 0xH4900, half [[ADD]] |
| ; CHECK-NEXT: ret half [[S]] |
| ; |
| %add = fdiv fast half %x, 10.0 |
| %cmp = fcmp ult half 100.0, %x |
| %s = select i1 %cmp, half 10.0, half %add |
| ret half %s |
| } |
| |
| define i8 @poison_false_val_negative(i8 %x) { |
| ; CHECK-LABEL: define i8 @poison_false_val_negative( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[X]], 16 |
| ; CHECK-NEXT: ret i8 [[ADD]] |
| ; |
| %add = add nsw i8 %x, 16 |
| %cmp = icmp sgt i8 %x, 8 |
| %s = select i1 %cmp, i8 %add, i8 poison |
| ret i8 %s |
| } |
| |
| define i8 @eq_negative(i8 %x) { |
| ; CHECK-LABEL: define i8 @eq_negative( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: ret i8 24 |
| ; |
| %add = add nsw i8 %x, 16 |
| %cmp = icmp eq i8 %x, 8 |
| %s = select i1 %cmp, i8 %add, i8 24 |
| ret i8 %s |
| } |
| |
| define i8 @different_operands_negative(i8 %x, i8 %y) { |
| ; CHECK-LABEL: define i8 @different_operands_negative( |
| ; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) { |
| ; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[X]], 16 |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[Y]], 8 |
| ; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i8 [[ADD]], i8 24 |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %add = add nsw i8 %x, 16 |
| %cmp = icmp sgt i8 %y, 8 |
| %s = select i1 %cmp, i8 %add, i8 24 |
| ret i8 %s |
| } |
| |
| define i8 @non_const_bop_operand_negative(i8 %x, i8 %y) { |
| ; CHECK-LABEL: define i8 @non_const_bop_operand_negative( |
| ; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) { |
| ; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[X]], [[Y]] |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[Y]], 8 |
| ; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i8 [[ADD]], i8 24 |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %add = add nsw i8 %x, %y |
| %cmp = icmp sgt i8 %y, 8 |
| %s = select i1 %cmp, i8 %add, i8 24 |
| ret i8 %s |
| } |
| |
| define i8 @non_const_cmp_operand_negative(i8 %x, i8 %y) { |
| ; CHECK-LABEL: define i8 @non_const_cmp_operand_negative( |
| ; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) { |
| ; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[X]], 16 |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X]], [[Y]] |
| ; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i8 [[ADD]], i8 24 |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %add = add nsw i8 %x, 16 |
| %cmp = icmp sgt i8 %x, %y |
| %s = select i1 %cmp, i8 %add, i8 24 |
| ret i8 %s |
| } |
| |
| declare i8 @result() |
| |
| define i8 @non_binop_negative(i8 %x) { |
| ; CHECK-LABEL: define i8 @non_binop_negative( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[RESULT:%.*]] = call i8 @result() |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X]], 16 |
| ; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i8 [[RESULT]], i8 24 |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %result = call i8 @result() |
| %cmp = icmp sgt i8 %x, 16 |
| %s = select i1 %cmp, i8 %result, i8 24 |
| ret i8 %s |
| } |
| |
| define i8 @sub_const_on_lhs_negative(i8 %x) { |
| ; CHECK-LABEL: define i8 @sub_const_on_lhs_negative( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i8 50, [[X]] |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[X]], 100 |
| ; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i8 [[SUB]], i8 50 |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %sub = sub nsw i8 50, %x |
| %cmp = icmp ugt i8 %x, 100 |
| %s = select i1 %cmp, i8 %sub, i8 50 |
| ret i8 %s |
| } |
| |
| define i8 @smin_ugt(i8 %x) { |
| ; CHECK-LABEL: define i8 @smin_ugt( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[S:%.*]] = call i8 @llvm.umin.i8(i8 [[X]], i8 50) |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %smin = call i8 @llvm.smin.i8(i8 %x, i8 50) |
| %cmp = icmp ugt i8 %x, 100 |
| %s = select i1 %cmp, i8 50, i8 %smin |
| ret i8 %s |
| } |
| |
| define i8 @smax_ugt(i8 %x) { |
| ; CHECK-LABEL: define i8 @smax_ugt( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[X]], i8 100) |
| ; CHECK-NEXT: [[S:%.*]] = call i8 @llvm.smax.i8(i8 [[TMP1]], i8 50) |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %smax = call i8 @llvm.smax.i8(i8 %x, i8 50) |
| %cmp = icmp ugt i8 %x, 100 |
| %s = select i1 %cmp, i8 100, i8 %smax |
| ret i8 %s |
| } |
| |
| define i8 @umin_slt(i8 %x) { |
| ; CHECK-LABEL: define i8 @umin_slt( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[X]], i8 0) |
| ; CHECK-NEXT: [[S:%.*]] = call i8 @llvm.umin.i8(i8 [[TMP1]], i8 100) |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %cmp = icmp slt i8 %x, 0 |
| %umin = tail call i8 @llvm.umin.i8(i8 %x, i8 100) |
| %s = select i1 %cmp, i8 0, i8 %umin |
| ret i8 %s |
| } |
| |
| define i8 @umax_sgt(i8 %x) { |
| ; CHECK-LABEL: define i8 @umax_sgt( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[X]], i8 100) |
| ; CHECK-NEXT: [[S:%.*]] = call i8 @llvm.umax.i8(i8 [[TMP1]], i8 50) |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %cmp = icmp sgt i8 %x, 100 |
| %umax = tail call i8 @llvm.umax.i8(i8 %x, i8 50) |
| %s = select i1 %cmp, i8 100, i8 %umax |
| ret i8 %s |
| } |
| |
| define i8 @add_sgt_nuw_nsw_safe(i8 %x) { |
| ; CHECK-LABEL: define i8 @add_sgt_nuw_nsw_safe( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[X]], i8 100) |
| ; CHECK-NEXT: [[S:%.*]] = add nuw nsw i8 [[TMP1]], 1 |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %add = add nuw nsw i8 %x, 1 |
| %cmp = icmp sgt i8 %x, 100 |
| %s = select i1 %cmp, i8 101, i8 %add |
| ret i8 %s |
| } |
| |
| define i8 @add_sgt_nuw_only(i8 %x) { |
| ; CHECK-LABEL: define i8 @add_sgt_nuw_only( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[X]], i8 100) |
| ; CHECK-NEXT: [[S:%.*]] = add nuw i8 [[TMP1]], 50 |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %add = add nuw nsw i8 %x, 50 |
| %cmp = icmp sgt i8 %x, 100 |
| %s = select i1 %cmp, i8 150, i8 %add |
| ret i8 %s |
| } |
| |
| define i8 @add_sgt_nsw_only(i8 %x) { |
| ; CHECK-LABEL: define i8 @add_sgt_nsw_only( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[X]], i8 100) |
| ; CHECK-NEXT: [[S:%.*]] = add nsw i8 [[TMP1]], -99 |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %add = add nuw nsw i8 %x, -99 |
| %cmp = icmp sgt i8 %x, 100 |
| %s = select i1 %cmp, i8 1, i8 %add |
| ret i8 %s |
| } |
| |
| |
| define i8 @mul_ult_nuw_nsw_safe(i8 %x) { |
| ; CHECK-LABEL: define i8 @mul_ult_nuw_nsw_safe( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[X]], i8 10) |
| ; CHECK-NEXT: [[S:%.*]] = mul nuw nsw i8 [[TMP1]], 3 |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %mul = mul nuw nsw i8 %x, 3 |
| %cmp = icmp ult i8 %x, 10 |
| %s = select i1 %cmp, i8 30, i8 %mul |
| ret i8 %s |
| } |
| |
| define i8 @mul_ult_nuw_only(i8 %x) { |
| ; CHECK-LABEL: define i8 @mul_ult_nuw_only( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[X]], i8 10) |
| ; CHECK-NEXT: [[S:%.*]] = mul nuw i8 [[TMP1]], 25 |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %mul = mul nuw nsw i8 %x, 25 |
| %cmp = icmp ult i8 %x, 10 |
| %s = select i1 %cmp, i8 250, i8 %mul |
| ret i8 %s |
| } |
| |
| define i8 @mul_ult_nsw_only(i8 %x) { |
| ; CHECK-LABEL: define i8 @mul_ult_nsw_only( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[X]], i8 40) |
| ; CHECK-NEXT: [[S:%.*]] = mul nsw i8 [[TMP1]], -2 |
| ; CHECK-NEXT: ret i8 [[S]] |
| ; |
| %mul = mul nuw nsw i8 %x, -2 |
| %cmp = icmp ult i8 %x, 40 |
| %s = select i1 %cmp, i8 -80, i8 %mul |
| ret i8 %s |
| } |