| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s |
| |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| ; |
| ; (ctpop(X) == N) || (X != 0) --> X != 0 |
| ; where N > 0 |
| ; |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| |
| declare i32 @llvm.ctpop.i32(i32) |
| |
| define i1 @eq_or_non_0(i32 %x) { |
| ; CHECK-LABEL: @eq_or_non_0( |
| ; CHECK-NEXT: [[NOTZERO:%.*]] = icmp ne i32 [[X:%.*]], 0 |
| ; CHECK-NEXT: ret i1 [[NOTZERO]] |
| ; |
| %t0 = tail call i32 @llvm.ctpop.i32(i32 %x) |
| %cmp = icmp eq i32 %t0, 10 |
| %notzero = icmp ne i32 %x, 0 |
| %r = or i1 %notzero, %cmp |
| ret i1 %r |
| } |
| |
| declare <2 x i32> @llvm.ctpop.v2i32(<2 x i32>) |
| |
| define <2 x i1> @eq_or_non_0_commute(<2 x i32> %x) { |
| ; CHECK-LABEL: @eq_or_non_0_commute( |
| ; CHECK-NEXT: [[NOTZERO:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer |
| ; CHECK-NEXT: ret <2 x i1> [[NOTZERO]] |
| ; |
| %t0 = tail call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %x) |
| %cmp = icmp eq <2 x i32> %t0, <i32 20, i32 20> |
| %notzero = icmp ne <2 x i32> %x, <i32 0, i32 0> |
| %r = or <2 x i1> %cmp, %notzero |
| ret <2 x i1> %r |
| } |
| |
| ; Negative test - wrong predicate |
| |
| define i1 @eq_or_non_0_wrong_pred1(i32 %x) { |
| ; CHECK-LABEL: @eq_or_non_0_wrong_pred1( |
| ; CHECK-NEXT: [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]) |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[T0]], 10 |
| ; CHECK-NEXT: [[NOTZERO:%.*]] = icmp ne i32 [[X]], 0 |
| ; CHECK-NEXT: [[R:%.*]] = or i1 [[NOTZERO]], [[CMP]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %t0 = tail call i32 @llvm.ctpop.i32(i32 %x) |
| %cmp = icmp ne i32 %t0, 10 |
| %notzero = icmp ne i32 %x, 0 |
| %r = or i1 %notzero, %cmp |
| ret i1 %r |
| } |
| |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| ; |
| ; (ctpop(X) != N) && (X == 0) --> X == 0 |
| ; where N > 0 |
| ; |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| |
| define i1 @ne_and_is_0(i32 %x) { |
| ; CHECK-LABEL: @ne_and_is_0( |
| ; CHECK-NEXT: [[ISZERO:%.*]] = icmp eq i32 [[X:%.*]], 0 |
| ; CHECK-NEXT: ret i1 [[ISZERO]] |
| ; |
| %t0 = tail call i32 @llvm.ctpop.i32(i32 %x) |
| %cmp = icmp ne i32 %t0, 10 |
| %iszero = icmp eq i32 %x, 0 |
| %r = and i1 %iszero, %cmp |
| ret i1 %r |
| } |
| |
| define <2 x i1> @ne_and_is_0_commute(<2 x i32> %x) { |
| ; CHECK-LABEL: @ne_and_is_0_commute( |
| ; CHECK-NEXT: [[ISZERO:%.*]] = icmp eq <2 x i32> [[X:%.*]], zeroinitializer |
| ; CHECK-NEXT: ret <2 x i1> [[ISZERO]] |
| ; |
| %t0 = tail call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %x) |
| %cmp = icmp ne <2 x i32> %t0, <i32 20, i32 20> |
| %iszero = icmp eq <2 x i32> %x, <i32 0, i32 0> |
| %r = and <2 x i1> %cmp, %iszero |
| ret <2 x i1> %r |
| } |
| |
| ; Negative test - wrong predicate |
| |
| define i1 @ne_and_is_0_wrong_pred1(i32 %x) { |
| ; CHECK-LABEL: @ne_and_is_0_wrong_pred1( |
| ; CHECK-NEXT: [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]) |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[T0]], 10 |
| ; CHECK-NEXT: [[ISZERO:%.*]] = icmp eq i32 [[X]], 0 |
| ; CHECK-NEXT: [[R:%.*]] = or i1 [[ISZERO]], [[CMP]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %t0 = tail call i32 @llvm.ctpop.i32(i32 %x) |
| %cmp = icmp ne i32 %t0, 10 |
| %iszero = icmp eq i32 %x, 0 |
| %r = or i1 %iszero, %cmp |
| ret i1 %r |
| } |