| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s |
| |
| define i1 @ult_query_via_signed_system(i64 %a, i64 %b, i64 %n) { |
| ; CHECK-LABEL: define i1 @ult_query_via_signed_system( |
| ; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]], i64 [[N:%.*]]) { |
| ; CHECK-NEXT: [[PRE_0:%.*]] = icmp sgt i64 [[B]], -1 |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[PRE_0]]) |
| ; CHECK-NEXT: [[S:%.*]] = sub nsw i64 [[A]], [[B]] |
| ; CHECK-NEXT: [[PRE_1:%.*]] = icmp sgt i64 [[S]], -1 |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[PRE_1]]) |
| ; CHECK-NEXT: [[PRE_2:%.*]] = icmp slt i64 [[A]], [[N]] |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[PRE_2]]) |
| ; CHECK-NEXT: ret i1 true |
| ; |
| %pre.0 = icmp sgt i64 %b, -1 |
| call void @llvm.assume(i1 %pre.0) |
| %s = sub nsw i64 %a, %b |
| %pre.1 = icmp sgt i64 %s, -1 |
| call void @llvm.assume(i1 %pre.1) |
| %pre.2 = icmp slt i64 %a, %n |
| call void @llvm.assume(i1 %pre.2) |
| %c = icmp ult i64 %s, %n |
| ret i1 %c |
| } |
| |
| ; Same as @ult_query_via_signed_system, but here the negation of the unsigned |
| ; query is proven. |
| define i1 @uge_query_via_signed_system(i64 %a, i64 %b, i64 %n) { |
| ; CHECK-LABEL: define i1 @uge_query_via_signed_system( |
| ; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]], i64 [[N:%.*]]) { |
| ; CHECK-NEXT: [[PRE_0:%.*]] = icmp sgt i64 [[B]], -1 |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[PRE_0]]) |
| ; CHECK-NEXT: [[S:%.*]] = sub nsw i64 [[A]], [[B]] |
| ; CHECK-NEXT: [[PRE_1:%.*]] = icmp sgt i64 [[S]], -1 |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[PRE_1]]) |
| ; CHECK-NEXT: [[PRE_2:%.*]] = icmp slt i64 [[A]], [[N]] |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[PRE_2]]) |
| ; CHECK-NEXT: ret i1 false |
| ; |
| %pre.0 = icmp sgt i64 %b, -1 |
| call void @llvm.assume(i1 %pre.0) |
| %s = sub nsw i64 %a, %b |
| %pre.1 = icmp sgt i64 %s, -1 |
| call void @llvm.assume(i1 %pre.1) |
| %pre.2 = icmp slt i64 %a, %n |
| call void @llvm.assume(i1 %pre.2) |
| %c = icmp uge i64 %s, %n |
| ret i1 %c |
| } |
| |
| define i1 @no_fold_operands_may_be_negative(i64 %a, i64 %b) { |
| ; CHECK-LABEL: define i1 @no_fold_operands_may_be_negative( |
| ; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) { |
| ; CHECK-NEXT: [[PRE_0:%.*]] = icmp slt i64 [[A]], [[B]] |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[PRE_0]]) |
| ; CHECK-NEXT: [[Q:%.*]] = icmp ult i64 [[A]], [[B]] |
| ; CHECK-NEXT: ret i1 [[Q]] |
| ; |
| %pre.0 = icmp slt i64 %a, %b |
| call void @llvm.assume(i1 %pre.0) |
| %q = icmp ult i64 %a, %b |
| ret i1 %q |
| } |
| |
| define i1 @no_fold_only_rhs_non_negative(i64 %a, i64 %b) { |
| ; CHECK-LABEL: define i1 @no_fold_only_rhs_non_negative( |
| ; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) { |
| ; CHECK-NEXT: [[PRE_0:%.*]] = icmp sgt i64 [[B]], -1 |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[PRE_0]]) |
| ; CHECK-NEXT: [[PRE_1:%.*]] = icmp slt i64 [[A]], [[B]] |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[PRE_1]]) |
| ; CHECK-NEXT: [[Q:%.*]] = icmp ult i64 [[A]], [[B]] |
| ; CHECK-NEXT: ret i1 [[Q]] |
| ; |
| %pre.0 = icmp sgt i64 %b, -1 |
| call void @llvm.assume(i1 %pre.0) |
| %pre.1 = icmp slt i64 %a, %b |
| call void @llvm.assume(i1 %pre.1) |
| %q = icmp ult i64 %a, %b |
| ret i1 %q |
| } |