233 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 42; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s3 4define i1 @abs_int_min_is_not_poison(i32 noundef %arg) {5; CHECK-LABEL: define i1 @abs_int_min_is_not_poison(6; CHECK-SAME: i32 noundef [[ARG:%.*]]) {7; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false)8; CHECK-NEXT: ret i1 true9;10 %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 false)11 %cmp = icmp sge i32 %abs, %arg12 ret i1 %cmp13}14 15define i1 @abs_int_min_is_poison(i32 noundef %arg) {16; CHECK-LABEL: define i1 @abs_int_min_is_poison(17; CHECK-SAME: i32 noundef [[ARG:%.*]]) {18; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true)19; CHECK-NEXT: ret i1 true20;21 %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true)22 %cmp = icmp sge i32 %abs, %arg23 ret i1 %cmp24}25 26define i1 @abs_plus_one_min_is_not_poison(i32 noundef %arg) {27; CHECK-LABEL: define i1 @abs_plus_one_min_is_not_poison(28; CHECK-SAME: i32 noundef [[ARG:%.*]]) {29; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false)30; CHECK-NEXT: [[ABS_PLUS_ONE:%.*]] = add nsw i32 [[ABS]], 131; CHECK-NEXT: ret i1 true32;33 %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 false)34 %abs_plus_one = add nsw i32 %abs, 135 %cmp = icmp sge i32 %abs_plus_one, %arg36 ret i1 %cmp37}38 39define i1 @abs_plus_one_min_is_poison(i32 noundef %arg) {40; CHECK-LABEL: define i1 @abs_plus_one_min_is_poison(41; CHECK-SAME: i32 noundef [[ARG:%.*]]) {42; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true)43; CHECK-NEXT: [[ABS_PLUS_ONE:%.*]] = add nsw i32 [[ABS]], 144; CHECK-NEXT: ret i1 true45;46 %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true)47 %abs_plus_one = add nsw i32 %abs, 148 %cmp = icmp sge i32 %abs_plus_one, %arg49 ret i1 %cmp50}51 52define i1 @arg_minus_one_strict_less_min_is_not_poison(i32 noundef %arg) {53; CHECK-LABEL: define i1 @arg_minus_one_strict_less_min_is_not_poison(54; CHECK-SAME: i32 noundef [[ARG:%.*]]) {55; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false)56; CHECK-NEXT: [[ARG_MINUS_ONE:%.*]] = add nsw i32 [[ARG]], -157; CHECK-NEXT: ret i1 true58;59 %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 false)60 %arg_minus_one = add nsw i32 %arg, -161 %cmp = icmp slt i32 %arg_minus_one, %abs62 ret i1 %cmp63}64 65 66define i1 @arg_minus_one_strict_less_min_is_poison(i32 noundef %arg) {67; CHECK-LABEL: define i1 @arg_minus_one_strict_less_min_is_poison(68; CHECK-SAME: i32 noundef [[ARG:%.*]]) {69; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true)70; CHECK-NEXT: [[ARG_MINUS_ONE:%.*]] = add nsw i32 [[ARG]], -171; CHECK-NEXT: ret i1 true72;73 %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true)74 %arg_minus_one = add nsw i32 %arg, -175 %cmp = icmp slt i32 %arg_minus_one, %abs76 ret i1 %cmp77}78 79define i1 @arg_minus_one_strict_greater_min_is_not_poison(i32 noundef %arg) {80; CHECK-LABEL: define i1 @arg_minus_one_strict_greater_min_is_not_poison(81; CHECK-SAME: i32 noundef [[ARG:%.*]]) {82; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false)83; CHECK-NEXT: [[ARG_MINUS_ONE:%.*]] = add nsw i32 [[ARG]], -184; CHECK-NEXT: ret i1 false85;86 %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 false)87 %arg_minus_one = add nsw i32 %arg, -188 %cmp = icmp sgt i32 %arg_minus_one, %abs89 ret i1 %cmp90}91 92define i1 @arg_minus_one_strict_greater_min_is_poison(i32 noundef %arg) {93; CHECK-LABEL: define i1 @arg_minus_one_strict_greater_min_is_poison(94; CHECK-SAME: i32 noundef [[ARG:%.*]]) {95; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true)96; CHECK-NEXT: [[ARG_MINUS_ONE:%.*]] = add nsw i32 [[ARG]], -197; CHECK-NEXT: ret i1 false98;99 %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true)100 %arg_minus_one = add nsw i32 %arg, -1101 %cmp = icmp sgt i32 %arg_minus_one, %abs102 ret i1 %cmp103}104 105define i1 @abs_plus_one_unsigned_greater_or_equal_nonnegative_arg_min_is_not_poison(i32 noundef %arg) {106; CHECK-LABEL: define i1 @abs_plus_one_unsigned_greater_or_equal_nonnegative_arg_min_is_not_poison(107; CHECK-SAME: i32 noundef [[ARG:%.*]]) {108; CHECK-NEXT: [[CMP_ARG_NONNEGATIVE:%.*]] = icmp sge i32 [[ARG]], 0109; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ARG_NONNEGATIVE]])110; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false)111; CHECK-NEXT: [[ABS_PLUS_ONE:%.*]] = add nuw i32 [[ABS]], 1112; CHECK-NEXT: ret i1 true113;114 %cmp_arg_nonnegative = icmp sge i32 %arg, 0115 call void @llvm.assume(i1 %cmp_arg_nonnegative)116 %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 false)117 %abs_plus_one = add nuw i32 %abs, 1118 %cmp = icmp uge i32 %abs_plus_one, %arg119 ret i1 %cmp120}121 122define i1 @abs_plus_one_unsigned_greater_or_equal_nonnegative_arg_min_is_poison(i32 noundef %arg) {123; CHECK-LABEL: define i1 @abs_plus_one_unsigned_greater_or_equal_nonnegative_arg_min_is_poison(124; CHECK-SAME: i32 noundef [[ARG:%.*]]) {125; CHECK-NEXT: [[CMP_ARG_NONNEGATIVE:%.*]] = icmp sge i32 [[ARG]], 0126; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ARG_NONNEGATIVE]])127; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true)128; CHECK-NEXT: [[ABS_PLUS_ONE:%.*]] = add nuw i32 [[ABS]], 1129; CHECK-NEXT: ret i1 true130;131 %cmp_arg_nonnegative = icmp sge i32 %arg, 0132 call void @llvm.assume(i1 %cmp_arg_nonnegative)133 %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true)134 %abs_plus_one = add nuw i32 %abs, 1135 %cmp = icmp uge i32 %abs_plus_one, %arg136 ret i1 %cmp137}138 139define i1 @abs_plus_one_unsigned_greater_or_equal_cannot_be_simplified(i32 noundef %arg) {140; CHECK-LABEL: define i1 @abs_plus_one_unsigned_greater_or_equal_cannot_be_simplified(141; CHECK-SAME: i32 noundef [[ARG:%.*]]) {142; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false)143; CHECK-NEXT: [[ABS_PLUS_ONE:%.*]] = add nuw i32 [[ABS]], 1144; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[ABS_PLUS_ONE]], [[ARG]]145; CHECK-NEXT: ret i1 [[CMP]]146;147 %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 false)148 %abs_plus_one = add nuw i32 %abs, 1149 %cmp = icmp uge i32 %abs_plus_one, %arg150 ret i1 %cmp151}152 153define i1 @abs_constant_negative_arg() {154; CHECK-LABEL: define i1 @abs_constant_negative_arg() {155; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 -3, i1 false)156; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[ABS]], 3157; CHECK-NEXT: ret i1 [[CMP]]158;159 %abs = tail call i32 @llvm.abs.i32(i32 -3, i1 false)160 %cmp = icmp sge i32 %abs, 3161 ret i1 %cmp162}163 164define i1 @abs_constant_positive_arg() {165; CHECK-LABEL: define i1 @abs_constant_positive_arg() {166; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 3, i1 false)167; CHECK-NEXT: ret i1 true168;169 %abs = tail call i32 @llvm.abs.i32(i32 3, i1 false)170 %cmp = icmp sge i32 %abs, 3171 ret i1 %cmp172}173 174define i1 @abs_is_nonnegative_except_for_int_min_if_int_min_is_not_poison(i32 noundef %arg) {175; CHECK-LABEL: define i1 @abs_is_nonnegative_except_for_int_min_if_int_min_is_not_poison(176; CHECK-SAME: i32 noundef [[ARG:%.*]]) {177; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false)178; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[ABS]], 0179; CHECK-NEXT: ret i1 [[CMP]]180;181 %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 false)182 %cmp = icmp sge i32 %abs, 0183 ret i1 %cmp184}185 186define i1 @abs_is_not_strictly_positive(i32 noundef %arg) {187; CHECK-LABEL: define i1 @abs_is_not_strictly_positive(188; CHECK-SAME: i32 noundef [[ARG:%.*]]) {189; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false)190; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[ABS]], 0191; CHECK-NEXT: ret i1 [[CMP]]192;193 %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 false)194 %cmp = icmp sgt i32 %abs, 0195 ret i1 %cmp196}197 198define i1 @abs_is_nonnegative_int_min_is_not_poison(i32 noundef %arg) {199; CHECK-LABEL: define i1 @abs_is_nonnegative_int_min_is_not_poison(200; CHECK-SAME: i32 noundef [[ARG:%.*]]) {201; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false)202; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[ABS]], 0203; CHECK-NEXT: ret i1 [[CMP]]204;205 %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 false)206 %cmp = icmp sge i32 %abs, 0207 ret i1 %cmp208}209 210define i1 @abs_is_nonnegative_int_min_is_poison(i32 noundef %arg) {211; CHECK-LABEL: define i1 @abs_is_nonnegative_int_min_is_poison(212; CHECK-SAME: i32 noundef [[ARG:%.*]]) {213; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true)214; CHECK-NEXT: ret i1 true215;216 %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true)217 %cmp = icmp sge i32 %abs, 0218 ret i1 %cmp219}220 221define i1 @abs_is_nonnegative_constant_arg() {222; CHECK-LABEL: define i1 @abs_is_nonnegative_constant_arg() {223; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 -3, i1 true)224; CHECK-NEXT: ret i1 true225;226 %abs = tail call i32 @llvm.abs.i32(i32 -3, i1 true)227 %cmp = icmp sge i32 %abs, 0228 ret i1 %cmp229}230 231declare i32 @llvm.abs.i32(i32, i1 immarg)232declare void @llvm.assume(i1)233