From: Sanjay Patel Date: Thu, 20 Jun 2019 15:25:18 +0000 (+0000) Subject: [InstCombine] add tests for checking power-of-2; NFC X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=11c1e438db0beed222e9f7cc56f7049bbb6a8328;p=llvm [InstCombine] add tests for checking power-of-2; NFC git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363938 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/Transforms/InstCombine/ispow2.ll b/test/Transforms/InstCombine/ispow2.ll new file mode 100644 index 00000000000..8ecc1856ba3 --- /dev/null +++ b/test/Transforms/InstCombine/ispow2.ll @@ -0,0 +1,138 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -instcombine -S | FileCheck %s + +define i1 @is_pow2or0_negate_op(i32 %x) { +; CHECK-LABEL: @is_pow2or0_negate_op( +; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[X:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and i32 [[NEG]], [[X]] +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], [[X]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %neg = sub i32 0, %x + %and = and i32 %neg, %x + %cmp = icmp eq i32 %and, %x + ret i1 %cmp +} + +define <2 x i1> @is_pow2or0_negate_op_vec(<2 x i32> %x) { +; CHECK-LABEL: @is_pow2or0_negate_op_vec( +; CHECK-NEXT: [[NEG:%.*]] = sub <2 x i32> zeroinitializer, [[X:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[NEG]], [[X]] +; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[AND]], [[X]] +; CHECK-NEXT: ret <2 x i1> [[CMP]] +; + %neg = sub <2 x i32> zeroinitializer, %x + %and = and <2 x i32> %neg, %x + %cmp = icmp eq <2 x i32> %and, %x + ret <2 x i1> %cmp +} + +define i1 @is_pow2or0_decrement_op(i8 %x) { +; CHECK-LABEL: @is_pow2or0_decrement_op( +; CHECK-NEXT: [[DEC:%.*]] = add i8 [[X:%.*]], -1 +; CHECK-NEXT: [[AND:%.*]] = and i8 [[DEC]], [[X]] +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %dec = add i8 %x, -1 + %and = and i8 %dec, %x + %cmp = icmp eq i8 %and, 0 + ret i1 %cmp +} + +define <2 x i1> @is_pow2or0_decrement_op_vec(<2 x i8> %x) { +; CHECK-LABEL: @is_pow2or0_decrement_op_vec( +; CHECK-NEXT: [[DEC:%.*]] = add <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[DEC]], [[X]] +; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[AND]], zeroinitializer +; CHECK-NEXT: ret <2 x i1> [[CMP]] +; + %dec = add <2 x i8> %x, + %and = and <2 x i8> %dec, %x + %cmp = icmp eq <2 x i8> %and, zeroinitializer + ret <2 x i1> %cmp +} + +define i1 @isnot_pow2or0_negate_op(i32 %x) { +; CHECK-LABEL: @isnot_pow2or0_negate_op( +; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[X:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and i32 [[NEG]], [[X]] +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], [[X]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %neg = sub i32 0, %x + %and = and i32 %neg, %x + %cmp = icmp ne i32 %and, %x + ret i1 %cmp +} + +define <2 x i1> @isnot_pow2or0_negate_op_vec(<2 x i32> %x) { +; CHECK-LABEL: @isnot_pow2or0_negate_op_vec( +; CHECK-NEXT: [[NEG:%.*]] = sub <2 x i32> zeroinitializer, [[X:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[NEG]], [[X]] +; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], [[X]] +; CHECK-NEXT: ret <2 x i1> [[CMP]] +; + %neg = sub <2 x i32> zeroinitializer, %x + %and = and <2 x i32> %neg, %x + %cmp = icmp ne <2 x i32> %and, %x + ret <2 x i1> %cmp +} + +define i1 @isnot_pow2or0_decrement_op(i8 %x) { +; CHECK-LABEL: @isnot_pow2or0_decrement_op( +; CHECK-NEXT: [[DEC:%.*]] = add i8 [[X:%.*]], -1 +; CHECK-NEXT: [[AND:%.*]] = and i8 [[DEC]], [[X]] +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %dec = add i8 %x, -1 + %and = and i8 %dec, %x + %cmp = icmp ne i8 %and, 0 + ret i1 %cmp +} + +define <2 x i1> @isnot_pow2or0_decrement_op_vec(<2 x i8> %x) { +; CHECK-LABEL: @isnot_pow2or0_decrement_op_vec( +; CHECK-NEXT: [[DEC:%.*]] = add <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[DEC]], [[X]] +; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i8> [[AND]], zeroinitializer +; CHECK-NEXT: ret <2 x i1> [[CMP]] +; + %dec = add <2 x i8> %x, + %and = and <2 x i8> %dec, %x + %cmp = icmp ne <2 x i8> %and, zeroinitializer + ret <2 x i1> %cmp +} + +declare void @use(i32) + +define i1 @is_pow2or0_negate_op_extra_use1(i32 %x) { +; CHECK-LABEL: @is_pow2or0_negate_op_extra_use1( +; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[X:%.*]] +; CHECK-NEXT: call void @use(i32 [[NEG]]) +; CHECK-NEXT: [[AND:%.*]] = and i32 [[NEG]], [[X]] +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], [[X]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %neg = sub i32 0, %x + call void @use(i32 %neg) + %and = and i32 %neg, %x + %cmp = icmp eq i32 %and, %x + ret i1 %cmp +} + +define i1 @is_pow2or0_negate_op_extra_use2(i32 %x) { +; CHECK-LABEL: @is_pow2or0_negate_op_extra_use2( +; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[X:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and i32 [[NEG]], [[X]] +; CHECK-NEXT: call void @use(i32 [[AND]]) +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], [[X]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %neg = sub i32 0, %x + %and = and i32 %neg, %x + call void @use(i32 %and) + %cmp = icmp eq i32 %and, %x + ret i1 %cmp +}