diff --git a/llvm/test/Transforms/InstCombine/integer-round-up-pow2-alignment.ll b/llvm/test/Transforms/InstCombine/integer-round-up-pow2-alignment.ll new file mode 100644 index 000000000000..eeeb9fb1e622 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/integer-round-up-pow2-alignment.ll @@ -0,0 +1,541 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes=instcombine -S | FileCheck %s + +declare void @use.i8(i8) +declare void @use.v2i4(<2 x i4>) +declare void @use.i1(i1) + +declare void @llvm.assume(i1) + +; Basic pattern +define i8 @t0(i8 %x) { +; CHECK-LABEL: @t0( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X:%.*]], 15 +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 0 +; CHECK-NEXT: [[X_BIASED:%.*]] = add i8 [[X]], 16 +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and i8 [[X_BIASED]], -16 +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X]], i8 [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]] +; + %x.lowbits = and i8 %x, 15 + %x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0 + %x.biased = add i8 %x, 16 + %x.biased.highbits = and i8 %x.biased, -16 + %x.roundedup = select i1 %x.lowbits.are.zero, i8 %x, i8 %x.biased.highbits + ret i8 %x.roundedup +} + +; Another alignment is fine +define i8 @t1(i8 %x) { +; CHECK-LABEL: @t1( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X:%.*]], 31 +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 0 +; CHECK-NEXT: [[X_BIASED:%.*]] = add i8 [[X]], 32 +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and i8 [[X_BIASED]], -32 +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X]], i8 [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]] +; + %x.lowbits = and i8 %x, 31 + %x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0 + %x.biased = add i8 %x, 32 + %x.biased.highbits = and i8 %x.biased, -32 + %x.roundedup = select i1 %x.lowbits.are.zero, i8 %x, i8 %x.biased.highbits + ret i8 %x.roundedup +} + +; Bias can be either the alignment or alignment-1 +define i8 @t2(i8 %x) { +; CHECK-LABEL: @t2( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X:%.*]], 15 +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 0 +; CHECK-NEXT: [[X_BIASED:%.*]] = add i8 [[X]], 15 +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and i8 [[X_BIASED]], -16 +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X]], i8 [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]] +; + %x.lowbits = and i8 %x, 15 + %x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0 + %x.biased = add i8 %x, 15 + %x.biased.highbits = and i8 %x.biased, -16 + %x.roundedup = select i1 %x.lowbits.are.zero, i8 %x, i8 %x.biased.highbits + ret i8 %x.roundedup +} + +; select is commutative +define i8 @t3_commutative(i8 %x) { +; CHECK-LABEL: @t3_commutative( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X:%.*]], 15 +; CHECK-NEXT: [[X_LOWBITS_ARE_NOT_ZERO:%.*]] = icmp ne i8 [[X_LOWBITS]], 0 +; CHECK-NEXT: call void @use.i1(i1 [[X_LOWBITS_ARE_NOT_ZERO]]) +; CHECK-NEXT: [[X_BIASED:%.*]] = add i8 [[X]], 16 +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and i8 [[X_BIASED]], -16 +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_NOT_ZERO]], i8 [[X_BIASED_HIGHBITS]], i8 [[X]] +; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]] +; + %x.lowbits = and i8 %x, 15 + %x.lowbits.are.not.zero = icmp ne i8 %x.lowbits, 0 + call void @use.i1(i1 %x.lowbits.are.not.zero) + %x.biased = add i8 %x, 16 + %x.biased.highbits = and i8 %x.biased, -16 + %x.roundedup = select i1 %x.lowbits.are.not.zero, i8 %x.biased.highbits, i8 %x + ret i8 %x.roundedup +} + +; Basic splat vector test +define <2 x i8> @t4_splat(<2 x i8> %x) { +; CHECK-LABEL: @t4_splat( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i8> [[X_LOWBITS]], zeroinitializer +; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i8> [[X]], +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i8> [[X_BIASED]], +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i8> [[X]], <2 x i8> [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret <2 x i8> [[X_ROUNDEDUP]] +; + %x.lowbits = and <2 x i8> %x, + %x.lowbits.are.zero = icmp eq <2 x i8> %x.lowbits, + %x.biased = add <2 x i8> %x, + %x.biased.highbits = and <2 x i8> %x.biased, + %x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i8> %x, <2 x i8> %x.biased.highbits + ret <2 x i8> %x.roundedup +} + +; Splat-with-undef +define <2 x i8> @t5_splat_undef_0b0001(<2 x i8> %x) { +; CHECK-LABEL: @t5_splat_undef_0b0001( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i8> [[X_LOWBITS]], zeroinitializer +; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i8> [[X]], +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i8> [[X_BIASED]], +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i8> [[X]], <2 x i8> [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret <2 x i8> [[X_ROUNDEDUP]] +; + %x.lowbits = and <2 x i8> %x, + %x.lowbits.are.zero = icmp eq <2 x i8> %x.lowbits, + %x.biased = add <2 x i8> %x, + %x.biased.highbits = and <2 x i8> %x.biased, + %x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i8> %x, <2 x i8> %x.biased.highbits + ret <2 x i8> %x.roundedup +} +define <2 x i8> @t5_splat_undef_0b0010(<2 x i8> %x) { +; CHECK-LABEL: @t5_splat_undef_0b0010( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i8> [[X_LOWBITS]], zeroinitializer +; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i8> [[X]], +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i8> [[X_BIASED]], +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i8> [[X]], <2 x i8> [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret <2 x i8> [[X_ROUNDEDUP]] +; + %x.lowbits = and <2 x i8> %x, + %x.lowbits.are.zero = icmp eq <2 x i8> %x.lowbits, + %x.biased = add <2 x i8> %x, + %x.biased.highbits = and <2 x i8> %x.biased, + %x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i8> %x, <2 x i8> %x.biased.highbits + ret <2 x i8> %x.roundedup +} +define <2 x i8> @t5_splat_undef_0b0100(<2 x i8> %x) { +; CHECK-LABEL: @t5_splat_undef_0b0100( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i8> [[X_LOWBITS]], +; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i8> [[X]], +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i8> [[X_BIASED]], +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i8> [[X]], <2 x i8> [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret <2 x i8> [[X_ROUNDEDUP]] +; + %x.lowbits = and <2 x i8> %x, + %x.lowbits.are.zero = icmp eq <2 x i8> %x.lowbits, + %x.biased = add <2 x i8> %x, + %x.biased.highbits = and <2 x i8> %x.biased, + %x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i8> %x, <2 x i8> %x.biased.highbits + ret <2 x i8> %x.roundedup +} +define <2 x i8> @t5_splat_undef_0b1000(<2 x i8> %x) { +; CHECK-LABEL: @t5_splat_undef_0b1000( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i8> [[X_LOWBITS]], zeroinitializer +; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i8> [[X]], +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i8> [[X_BIASED]], +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i8> [[X]], <2 x i8> [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret <2 x i8> [[X_ROUNDEDUP]] +; + %x.lowbits = and <2 x i8> %x, + %x.lowbits.are.zero = icmp eq <2 x i8> %x.lowbits, + %x.biased = add <2 x i8> %x, + %x.biased.highbits = and <2 x i8> %x.biased, + %x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i8> %x, <2 x i8> %x.biased.highbits + ret <2 x i8> %x.roundedup +} + +; Basic non-splat vector test +define <2 x i8> @t6_nonsplat(<2 x i8> %x) { +; CHECK-LABEL: @t6_nonsplat( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i8> [[X_LOWBITS]], zeroinitializer +; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i8> [[X]], +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i8> [[X_BIASED]], +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i8> [[X]], <2 x i8> [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret <2 x i8> [[X_ROUNDEDUP]] +; + %x.lowbits = and <2 x i8> %x, + %x.lowbits.are.zero = icmp eq <2 x i8> %x.lowbits, + %x.biased = add <2 x i8> %x, + %x.biased.highbits = and <2 x i8> %x.biased, + %x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i8> %x, <2 x i8> %x.biased.highbits + ret <2 x i8> %x.roundedup +} + +; Even if the alignment (and masks) are splat, the bias could be non-splat +define <2 x i8> @t7_nonsplat_bias(<2 x i8> %x) { +; CHECK-LABEL: @t7_nonsplat_bias( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i8> [[X_LOWBITS]], zeroinitializer +; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i8> [[X]], +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i8> [[X_BIASED]], +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i8> [[X]], <2 x i8> [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret <2 x i8> [[X_ROUNDEDUP]] +; + %x.lowbits = and <2 x i8> %x, + %x.lowbits.are.zero = icmp eq <2 x i8> %x.lowbits, + %x.biased = add <2 x i8> %x, + %x.biased.highbits = and <2 x i8> %x.biased, + %x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i8> %x, <2 x i8> %x.biased.highbits + ret <2 x i8> %x.roundedup +} + +; Splat-in-disguise vector tests +define <2 x i8> @t8_nonsplat_masked_by_undef_0b0001(<2 x i8> %x) { +; CHECK-LABEL: @t8_nonsplat_masked_by_undef_0b0001( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i8> [[X_LOWBITS]], zeroinitializer +; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i8> [[X]], +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i8> [[X_BIASED]], +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i8> [[X]], <2 x i8> [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret <2 x i8> [[X_ROUNDEDUP]] +; + %x.lowbits = and <2 x i8> %x, + %x.lowbits.are.zero = icmp eq <2 x i8> %x.lowbits, + %x.biased = add <2 x i8> %x, + %x.biased.highbits = and <2 x i8> %x.biased, + %x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i8> %x, <2 x i8> %x.biased.highbits + ret <2 x i8> %x.roundedup +} +define <2 x i8> @t8_nonsplat_masked_by_undef_0b0010(<2 x i8> %x) { +; CHECK-LABEL: @t8_nonsplat_masked_by_undef_0b0010( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i8> [[X_LOWBITS]], zeroinitializer +; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i8> [[X]], +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i8> [[X_BIASED]], +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i8> [[X]], <2 x i8> [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret <2 x i8> [[X_ROUNDEDUP]] +; + %x.lowbits = and <2 x i8> %x, + %x.lowbits.are.zero = icmp eq <2 x i8> %x.lowbits, + %x.biased = add <2 x i8> %x, + %x.biased.highbits = and <2 x i8> %x.biased, + %x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i8> %x, <2 x i8> %x.biased.highbits + ret <2 x i8> %x.roundedup +} +define <2 x i8> @t8_nonsplat_masked_by_undef_0b0100(<2 x i8> %x) { +; CHECK-LABEL: @t8_nonsplat_masked_by_undef_0b0100( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i8> [[X_LOWBITS]], +; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i8> [[X]], +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i8> [[X_BIASED]], +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i8> [[X]], <2 x i8> [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret <2 x i8> [[X_ROUNDEDUP]] +; + %x.lowbits = and <2 x i8> %x, + %x.lowbits.are.zero = icmp eq <2 x i8> %x.lowbits, + %x.biased = add <2 x i8> %x, + %x.biased.highbits = and <2 x i8> %x.biased, + %x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i8> %x, <2 x i8> %x.biased.highbits + ret <2 x i8> %x.roundedup +} +define <2 x i8> @t8_nonsplat_masked_by_undef_0b1000(<2 x i8> %x) { +; CHECK-LABEL: @t8_nonsplat_masked_by_undef_0b1000( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i8> [[X_LOWBITS]], zeroinitializer +; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i8> [[X]], +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i8> [[X_BIASED]], +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i8> [[X]], <2 x i8> [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret <2 x i8> [[X_ROUNDEDUP]] +; + %x.lowbits = and <2 x i8> %x, + %x.lowbits.are.zero = icmp eq <2 x i8> %x.lowbits, + %x.biased = add <2 x i8> %x, + %x.biased.highbits = and <2 x i8> %x.biased, + %x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i8> %x, <2 x i8> %x.biased.highbits + ret <2 x i8> %x.roundedup +} + +; The X are different +define i8 @n9_wrong_x0(i8 %x.0, i8 %x.1) { +; CHECK-LABEL: @n9_wrong_x0( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X_0:%.*]], 15 +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 0 +; CHECK-NEXT: [[X_BIASED:%.*]] = add i8 [[X_0]], 16 +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and i8 [[X_BIASED]], -16 +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X_1:%.*]], i8 [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]] +; + %x.lowbits = and i8 %x.0, 15 + %x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0 + %x.biased = add i8 %x.0, 16 + %x.biased.highbits = and i8 %x.biased, -16 + %x.roundedup = select i1 %x.lowbits.are.zero, i8 %x.1, i8 %x.biased.highbits + ret i8 %x.roundedup +} +define i8 @n9_wrong_x1(i8 %x.0, i8 %x.1) { +; CHECK-LABEL: @n9_wrong_x1( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X_0:%.*]], 15 +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 0 +; CHECK-NEXT: [[X_BIASED:%.*]] = add i8 [[X_1:%.*]], 16 +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and i8 [[X_BIASED]], -16 +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X_0]], i8 [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]] +; + %x.lowbits = and i8 %x.0, 15 + %x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0 + %x.biased = add i8 %x.1, 16 + %x.biased.highbits = and i8 %x.biased, -16 + %x.roundedup = select i1 %x.lowbits.are.zero, i8 %x.0, i8 %x.biased.highbits + ret i8 %x.roundedup +} +define i8 @n9_wrong_x2(i8 %x.0, i8 %x.1) { +; CHECK-LABEL: @n9_wrong_x2( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X_1:%.*]], 15 +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 0 +; CHECK-NEXT: [[X_BIASED:%.*]] = add i8 [[X_0:%.*]], 16 +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and i8 [[X_BIASED]], -16 +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X_0]], i8 [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]] +; + %x.lowbits = and i8 %x.1, 15 + %x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0 + %x.biased = add i8 %x.0, 16 + %x.biased.highbits = and i8 %x.biased, -16 + %x.roundedup = select i1 %x.lowbits.are.zero, i8 %x.0, i8 %x.biased.highbits + ret i8 %x.roundedup +} + +; Wrong low-bit mask +define i8 @n10_wrong_low_bit_mask(i8 %x) { +; CHECK-LABEL: @n10_wrong_low_bit_mask( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X:%.*]], 31 +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 0 +; CHECK-NEXT: [[X_BIASED:%.*]] = add i8 [[X]], 16 +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and i8 [[X_BIASED]], -16 +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X]], i8 [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]] +; + %x.lowbits = and i8 %x, 31 + %x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0 + %x.biased = add i8 %x, 16 + %x.biased.highbits = and i8 %x.biased, -16 + %x.roundedup = select i1 %x.lowbits.are.zero, i8 %x, i8 %x.biased.highbits + ret i8 %x.roundedup +} + +; Wrong high-bit mask +define i8 @n11_wrong_high_bit_mask(i8 %x) { +; CHECK-LABEL: @n11_wrong_high_bit_mask( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X:%.*]], 15 +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 0 +; CHECK-NEXT: [[X_BIASED:%.*]] = add i8 [[X]], 16 +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and i8 [[X_BIASED]], -32 +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X]], i8 [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]] +; + %x.lowbits = and i8 %x, 15 + %x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0 + %x.biased = add i8 %x, 16 + %x.biased.highbits = and i8 %x.biased, -32 + %x.roundedup = select i1 %x.lowbits.are.zero, i8 %x, i8 %x.biased.highbits + ret i8 %x.roundedup +} + +; Wrong bias +define i8 @n12_wrong_bias(i8 %x) { +; CHECK-LABEL: @n12_wrong_bias( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X:%.*]], 15 +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 0 +; CHECK-NEXT: [[X_BIASED:%.*]] = add i8 [[X]], 32 +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and i8 [[X_BIASED]], -16 +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X]], i8 [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]] +; + %x.lowbits = and i8 %x, 15 + %x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0 + %x.biased = add i8 %x, 32 + %x.biased.highbits = and i8 %x.biased, -16 + %x.roundedup = select i1 %x.lowbits.are.zero, i8 %x, i8 %x.biased.highbits + ret i8 %x.roundedup +} + +; Wrong constants +define i8 @n13_wrong_constants_alignment_is_not_power_of_two(i8 %x) { +; CHECK-LABEL: @n13_wrong_constants_alignment_is_not_power_of_two( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X:%.*]], 2 +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 0 +; CHECK-NEXT: [[X_BIASED:%.*]] = add i8 [[X]], 3 +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and i8 [[X_BIASED]], -3 +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X]], i8 [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]] +; + %x.lowbits = and i8 %x, 2 + %x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0 + %x.biased = add i8 %x, 3 + %x.biased.highbits = and i8 %x.biased, -3 + %x.roundedup = select i1 %x.lowbits.are.zero, i8 %x, i8 %x.biased.highbits + ret i8 %x.roundedup +} + +; Comparison is not with zero +define i8 @n14_wrong_comparison_constant(i8 %x) { +; CHECK-LABEL: @n14_wrong_comparison_constant( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X:%.*]], 15 +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 1 +; CHECK-NEXT: [[X_BIASED:%.*]] = add i8 [[X]], 16 +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and i8 [[X_BIASED]], -16 +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X]], i8 [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]] +; + %x.lowbits = and i8 %x, 15 + %x.lowbits.are.zero = icmp eq i8 %x.lowbits, 1 + %x.biased = add i8 %x, 16 + %x.biased.highbits = and i8 %x.biased, -16 + %x.roundedup = select i1 %x.lowbits.are.zero, i8 %x, i8 %x.biased.highbits + ret i8 %x.roundedup +} + +; Wrong comparison +define i8 @n15_wrong_comparison_predicate_and_constant(i8 %x) { +; CHECK-LABEL: @n15_wrong_comparison_predicate_and_constant( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X:%.*]], 14 +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 0 +; CHECK-NEXT: [[X_BIASED:%.*]] = add i8 [[X]], 16 +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and i8 [[X_BIASED]], -16 +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X]], i8 [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]] +; + %x.lowbits = and i8 %x, 15 + %x.lowbits.are.zero = icmp ult i8 %x.lowbits, 2 + %x.biased = add i8 %x, 16 + %x.biased.highbits = and i8 %x.biased, -16 + %x.roundedup = select i1 %x.lowbits.are.zero, i8 %x, i8 %x.biased.highbits + ret i8 %x.roundedup +} + +; %x.biased.highbits must not have other uses +define i8 @n16_oneuse(i8 %x) { +; CHECK-LABEL: @n16_oneuse( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X:%.*]], 15 +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 0 +; CHECK-NEXT: [[X_BIASED:%.*]] = add i8 [[X]], 16 +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and i8 [[X_BIASED]], -16 +; CHECK-NEXT: call void @use.i8(i8 [[X_BIASED_HIGHBITS]]) +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X]], i8 [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]] +; + %x.lowbits = and i8 %x, 15 + %x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0 + %x.biased = add i8 %x, 16 + %x.biased.highbits = and i8 %x.biased, -16 + call void @use.i8(i8 %x.biased.highbits) + %x.roundedup = select i1 %x.lowbits.are.zero, i8 %x, i8 %x.biased.highbits + ret i8 %x.roundedup +} + +; But if bias is equal to low-bit mask, then we *could* just replace %x.roundedup with %x.biased.highbits +define i8 @t17_oneuse(i8 %x) { +; CHECK-LABEL: @t17_oneuse( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and i8 [[X:%.*]], 15 +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq i8 [[X_LOWBITS]], 0 +; CHECK-NEXT: [[X_BIASED:%.*]] = add i8 [[X]], 15 +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and i8 [[X_BIASED]], -16 +; CHECK-NEXT: call void @use.i8(i8 [[X_BIASED_HIGHBITS]]) +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select i1 [[X_LOWBITS_ARE_ZERO]], i8 [[X]], i8 [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret i8 [[X_ROUNDEDUP]] +; + %x.lowbits = and i8 %x, 15 + %x.lowbits.are.zero = icmp eq i8 %x.lowbits, 0 + %x.biased = add i8 %x, 15 + %x.biased.highbits = and i8 %x.biased, -16 + call void @use.i8(i8 %x.biased.highbits) + %x.roundedup = select i1 %x.lowbits.are.zero, i8 %x, i8 %x.biased.highbits + ret i8 %x.roundedup +} + +; Bias is equal to the alignment-1 (as opposed to alignment), +; so we can just replace %x.roundedup with %x.biased.highbits +define <2 x i4> @t18_replacement_0b0001(<2 x i4> %x) { +; CHECK-LABEL: @t18_replacement_0b0001( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i4> [[X:%.*]], +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i4> [[X_LOWBITS]], zeroinitializer +; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i4> [[X]], +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i4> [[X_BIASED]], +; CHECK-NEXT: call void @use.v2i4(<2 x i4> [[X_BIASED_HIGHBITS]]) +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i4> [[X]], <2 x i4> [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret <2 x i4> [[X_ROUNDEDUP]] +; + %x.lowbits = and <2 x i4> %x, + %x.lowbits.are.zero = icmp eq <2 x i4> %x.lowbits, + %x.biased = add <2 x i4> %x, + %x.biased.highbits = and <2 x i4> %x.biased, + call void @use.v2i4(<2 x i4> %x.biased.highbits) + %x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i4> %x, <2 x i4> %x.biased.highbits + ret <2 x i4> %x.roundedup +} +define <2 x i4> @t18_replacement_0b0010(<2 x i4> %x) { +; CHECK-LABEL: @t18_replacement_0b0010( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i4> [[X:%.*]], +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i4> [[X_LOWBITS]], zeroinitializer +; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i4> [[X]], +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i4> [[X_BIASED]], +; CHECK-NEXT: call void @use.v2i4(<2 x i4> [[X_BIASED_HIGHBITS]]) +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i4> [[X]], <2 x i4> [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret <2 x i4> [[X_ROUNDEDUP]] +; + %x.lowbits = and <2 x i4> %x, + %x.lowbits.are.zero = icmp eq <2 x i4> %x.lowbits, + %x.biased = add <2 x i4> %x, + %x.biased.highbits = and <2 x i4> %x.biased, + call void @use.v2i4(<2 x i4> %x.biased.highbits) + %x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i4> %x, <2 x i4> %x.biased.highbits + ret <2 x i4> %x.roundedup +} +define <2 x i4> @t18_replacement_0b0100(<2 x i4> %x) { +; CHECK-LABEL: @t18_replacement_0b0100( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i4> [[X:%.*]], +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i4> [[X_LOWBITS]], +; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i4> [[X]], +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i4> [[X_BIASED]], +; CHECK-NEXT: call void @use.v2i4(<2 x i4> [[X_BIASED_HIGHBITS]]) +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i4> [[X]], <2 x i4> [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret <2 x i4> [[X_ROUNDEDUP]] +; + %x.lowbits = and <2 x i4> %x, + %x.lowbits.are.zero = icmp eq <2 x i4> %x.lowbits, + %x.biased = add <2 x i4> %x, + %x.biased.highbits = and <2 x i4> %x.biased, + call void @use.v2i4(<2 x i4> %x.biased.highbits) + %x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i4> %x, <2 x i4> %x.biased.highbits + ret <2 x i4> %x.roundedup +} +define <2 x i4> @t18_replacement_0b1000(<2 x i4> %x) { +; CHECK-LABEL: @t18_replacement_0b1000( +; CHECK-NEXT: [[X_LOWBITS:%.*]] = and <2 x i4> [[X:%.*]], +; CHECK-NEXT: [[X_LOWBITS_ARE_ZERO:%.*]] = icmp eq <2 x i4> [[X_LOWBITS]], zeroinitializer +; CHECK-NEXT: [[X_BIASED:%.*]] = add <2 x i4> [[X]], +; CHECK-NEXT: [[X_BIASED_HIGHBITS:%.*]] = and <2 x i4> [[X_BIASED]], +; CHECK-NEXT: call void @use.v2i4(<2 x i4> [[X_BIASED_HIGHBITS]]) +; CHECK-NEXT: [[X_ROUNDEDUP:%.*]] = select <2 x i1> [[X_LOWBITS_ARE_ZERO]], <2 x i4> [[X]], <2 x i4> [[X_BIASED_HIGHBITS]] +; CHECK-NEXT: ret <2 x i4> [[X_ROUNDEDUP]] +; + %x.lowbits = and <2 x i4> %x, + %x.lowbits.are.zero = icmp eq <2 x i4> %x.lowbits, + %x.biased = add <2 x i4> %x, + %x.biased.highbits = and <2 x i4> %x.biased, + call void @use.v2i4(<2 x i4> %x.biased.highbits) + %x.roundedup = select <2 x i1> %x.lowbits.are.zero, <2 x i4> %x, <2 x i4> %x.biased.highbits + ret <2 x i4> %x.roundedup +}