blob: 44565f8d1341fe0e4685b3ac18a3eb01654256f1 [file] [log] [blame]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
define i1 @idx_known_positive_via_len_1(i8 %len, i8 %idx) {
; CHECK-LABEL: @idx_known_positive_via_len_1(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[IDX_ULT_LEN:%.*]] = icmp samesign ult i8 [[IDX:%.*]], [[LEN:%.*]]
; CHECK-NEXT: [[AND_1:%.*]] = and i1 true, [[IDX_ULT_LEN]]
; CHECK-NEXT: br i1 [[AND_1]], label [[THEN_1:%.*]], label [[ELSE:%.*]]
; CHECK: then.1:
; CHECK-NEXT: [[R_1:%.*]] = xor i1 true, true
; CHECK-NEXT: [[C_1:%.*]] = icmp sge i8 [[IDX]], 1
; CHECK-NEXT: [[R_2:%.*]] = xor i1 [[R_1]], [[C_1]]
; CHECK-NEXT: [[C_2:%.*]] = icmp sge i8 [[LEN]], 1
; CHECK-NEXT: [[R_3:%.*]] = xor i1 [[R_2]], [[C_2]]
; CHECK-NEXT: ret i1 [[R_3]]
; CHECK: else:
; CHECK-NEXT: [[C_3:%.*]] = icmp sge i8 [[IDX]], 0
; CHECK-NEXT: ret i1 [[C_3]]
;
entry:
%len.pos = icmp samesign uge i8 %len, 0
%idx.ult.len = icmp samesign ult i8 %idx, %len
%and.1 = and i1 %len.pos, %idx.ult.len
br i1 %and.1, label %then.1, label %else
then.1:
%t.1 = icmp slt i8 %idx, %len
%t.2 = icmp samesign uge i8 %idx, 0
%r.1 = xor i1 %t.1, %t.2
%c.1 = icmp sge i8 %idx, 1
%r.2 = xor i1 %r.1, %c.1
%c.2 = icmp sge i8 %len, 1
%r.3 = xor i1 %r.2, %c.2
ret i1 %r.3
else:
%c.3 = icmp sge i8 %idx, 0
ret i1 %c.3
}
; Like @idx_known_positive_via_len_1, but with a different order of known facts.
define i1 @idx_known_positive_via_len_2(i8 %len, i8 %idx) {
; CHECK-LABEL: @idx_known_positive_via_len_2(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[IDX_ULT_LEN:%.*]] = icmp samesign ult i8 [[IDX:%.*]], [[LEN:%.*]]
; CHECK-NEXT: [[AND_1:%.*]] = and i1 true, [[IDX_ULT_LEN]]
; CHECK-NEXT: br i1 [[AND_1]], label [[THEN_1:%.*]], label [[ELSE:%.*]]
; CHECK: then.1:
; CHECK-NEXT: [[R_1:%.*]] = xor i1 true, true
; CHECK-NEXT: [[C_1:%.*]] = icmp sge i8 [[IDX]], 1
; CHECK-NEXT: [[R_2:%.*]] = xor i1 [[R_1]], [[C_1]]
; CHECK-NEXT: [[C_2:%.*]] = icmp sge i8 [[LEN]], 1
; CHECK-NEXT: [[R_3:%.*]] = xor i1 [[R_2]], [[C_2]]
; CHECK-NEXT: ret i1 [[R_3]]
; CHECK: else:
; CHECK-NEXT: [[C_3:%.*]] = icmp sge i8 [[IDX]], 0
; CHECK-NEXT: ret i1 [[C_3]]
;
entry:
%idx.ult.len = icmp samesign ult i8 %idx, %len
%len.pos = icmp samesign uge i8 %len, 0
%and.1 = and i1 %len.pos, %idx.ult.len
br i1 %and.1, label %then.1, label %else
then.1:
%t.1 = icmp slt i8 %idx, %len
%t.2 = icmp samesign uge i8 %idx, 0
%r.1 = xor i1 %t.1, %t.2
%c.1 = icmp sge i8 %idx, 1
%r.2 = xor i1 %r.1, %c.1
%c.2 = icmp sge i8 %len, 1
%r.3 = xor i1 %r.2, %c.2
ret i1 %r.3
else:
%c.3 = icmp sge i8 %idx, 0
ret i1 %c.3
}
define i1 @idx_not_known_positive_via_len_uge(i8 %len, i8 %idx) {
; CHECK-LABEL: @idx_not_known_positive_via_len_uge(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[IDX_ULT_LEN:%.*]] = icmp samesign ult i8 [[IDX:%.*]], [[LEN:%.*]]
; CHECK-NEXT: br i1 [[IDX_ULT_LEN]], label [[THEN_1:%.*]], label [[ELSE:%.*]]
; CHECK: then.1:
; CHECK-NEXT: [[C_2:%.*]] = icmp sge i8 [[IDX]], 0
; CHECK-NEXT: [[R_1:%.*]] = xor i1 true, [[C_2]]
; CHECK-NEXT: [[C_3:%.*]] = icmp sge i8 [[IDX]], 1
; CHECK-NEXT: [[R_2:%.*]] = xor i1 [[R_1]], [[C_3]]
; CHECK-NEXT: [[C_4:%.*]] = icmp sge i8 [[LEN]], 1
; CHECK-NEXT: [[R_3:%.*]] = xor i1 [[R_2]], [[C_4]]
; CHECK-NEXT: ret i1 [[R_3]]
; CHECK: else:
; CHECK-NEXT: [[C_5:%.*]] = icmp sge i8 [[IDX]], 0
; CHECK-NEXT: ret i1 [[C_5]]
;
entry:
%idx.ult.len = icmp samesign ult i8 %idx, %len
br i1 %idx.ult.len, label %then.1, label %else
then.1:
%c.1 = icmp slt i8 %idx, %len
%c.2 = icmp sge i8 %idx, 0
%r.1 = xor i1 %c.1, %c.2
%c.3 = icmp sge i8 %idx, 1
%r.2 = xor i1 %r.1, %c.3
%c.4 = icmp sge i8 %len, 1
%r.3 = xor i1 %r.2, %c.4
ret i1 %r.3
else:
%c.5 = icmp sge i8 %idx, 0
ret i1 %c.5
}
define i1 @idx_not_known_positive_via_len(i8 %len, i8 %idx) {
; CHECK-LABEL: @idx_not_known_positive_via_len(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[IDX_ULT_LEN:%.*]] = icmp samesign ult i8 [[IDX:%.*]], [[LEN:%.*]]
; CHECK-NEXT: br i1 [[IDX_ULT_LEN]], label [[THEN_1:%.*]], label [[ELSE:%.*]]
; CHECK: then.1:
; CHECK-NEXT: [[C_2:%.*]] = icmp sge i8 [[IDX]], 0
; CHECK-NEXT: [[R_1:%.*]] = xor i1 true, [[C_2]]
; CHECK-NEXT: [[C_3:%.*]] = icmp sge i8 [[IDX]], 1
; CHECK-NEXT: [[R_2:%.*]] = xor i1 [[R_1]], [[C_3]]
; CHECK-NEXT: [[C_4:%.*]] = icmp sge i8 [[LEN]], 1
; CHECK-NEXT: [[R_3:%.*]] = xor i1 [[R_2]], [[C_4]]
; CHECK-NEXT: ret i1 [[R_3]]
; CHECK: else:
; CHECK-NEXT: [[C_5:%.*]] = icmp sge i8 [[IDX]], 0
; CHECK-NEXT: ret i1 [[C_5]]
;
entry:
%idx.ult.len = icmp samesign ult i8 %idx, %len
br i1 %idx.ult.len, label %then.1, label %else
then.1:
%c.1 = icmp slt i8 %idx, %len
%c.2 = icmp sge i8 %idx, 0
%r.1 = xor i1 %c.1, %c.2
%c.3 = icmp sge i8 %idx, 1
%r.2 = xor i1 %r.1, %c.3
%c.4 = icmp sge i8 %len, 1
%r.3 = xor i1 %r.2, %c.4
ret i1 %r.3
else:
%c.5 = icmp sge i8 %idx, 0
ret i1 %c.5
}
define i1 @ult_signed_pos_constant(i8 %a) {
; CHECK-LABEL: @ult_signed_pos_constant(
; CHECK-NEXT: [[A_ULT_4:%.*]] = icmp samesign ult i8 [[A:%.*]], 4
; CHECK-NEXT: br i1 [[A_ULT_4]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
; CHECK-NEXT: [[RES_1:%.*]] = icmp sge i8 [[A]], 0
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], true
; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_2]], true
; CHECK-NEXT: ret i1 [[RES_5]]
; CHECK: else:
; CHECK-NEXT: [[RES_3:%.*]] = xor i1 true, false
; CHECK-NEXT: [[C_4:%.*]] = icmp slt i8 [[A]], 5
; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_4]]
; CHECK-NEXT: ret i1 [[RES_4]]
;
%a.ult.4 = icmp samesign ult i8 %a, 4
br i1 %a.ult.4, label %then, label %else
then:
%t.0 = icmp sge i8 %a, 0
%t.1 = icmp slt i8 %a, 4
%res.1 = xor i1 %t.0, %t.1
%c.0 = icmp slt i8 %a, 5
%res.2 = xor i1 %res.1, %c.0
ret i1 %res.2
else:
%c.2 = icmp sge i8 %a, 0
%c.3 = icmp slt i8 %a, 4
%res.3 = xor i1 %c.2, %c.3
%c.4 = icmp slt i8 %a, 5
%res.4 = xor i1 %res.3, %c.4
ret i1 %res.4
}
define i1 @ult_signed_neg_constant(i8 %a) {
; CHECK-LABEL: @ult_signed_neg_constant(
; CHECK-NEXT: [[A_ULT_4:%.*]] = icmp samesign ult i8 [[A:%.*]], -2
; CHECK-NEXT: br i1 [[A_ULT_4]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 false, true
; CHECK-NEXT: ret i1 [[RES_1]]
; CHECK: else:
; CHECK-NEXT: ret i1 false
;
%a.ult.4 = icmp samesign ult i8 %a, -2
br i1 %a.ult.4, label %then, label %else
then:
%c.0 = icmp sge i8 %a, 0
%c.1 = icmp slt i8 %a, -2
%res.1 = xor i1 %c.0, %c.1
ret i1 %res.1
else:
ret i1 0
}
define i1 @ule_signed_pos_constant_1(i8 %a, i8 %b) {
; CHECK-LABEL: @ule_signed_pos_constant_1(
; CHECK-NEXT: [[A_ULE_B:%.*]] = icmp samesign ule i8 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: call void @llvm.assume(i1 [[A_ULE_B]])
; CHECK-NEXT: [[SLT_TEST:%.*]] = icmp slt i8 [[A]], [[B]]
; CHECK-NEXT: [[RESULT_XOR:%.*]] = xor i1 true, [[SLT_TEST]]
; CHECK-NEXT: ret i1 [[RESULT_XOR]]
;
%a_ule_b = icmp samesign ule i8 %a, %b
call void @llvm.assume(i1 %a_ule_b)
%sle_test = icmp sle i8 %a, %b
%slt_test = icmp slt i8 %a, %b
%result_xor = xor i1 %sle_test, %slt_test
ret i1 %result_xor
}
define i1 @ule_signed_pos_constant_2(i8 %a) {
; CHECK-LABEL: @ule_signed_pos_constant_2(
; CHECK-NEXT: [[A_ULT_4:%.*]] = icmp samesign ule i8 [[A:%.*]], 4
; CHECK-NEXT: br i1 [[A_ULT_4]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
; CHECK-NEXT: [[RES_1:%.*]] = icmp sge i8 [[A]], 0
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], true
; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_2]], true
; CHECK-NEXT: ret i1 [[RES_5]]
; CHECK: else:
; CHECK-NEXT: [[RES_3:%.*]] = xor i1 true, false
; CHECK-NEXT: [[C_4:%.*]] = icmp sle i8 [[A]], 5
; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_4]]
; CHECK-NEXT: ret i1 [[RES_4]]
;
%a.ult.4 = icmp samesign ule i8 %a, 4
br i1 %a.ult.4, label %then, label %else
then:
%t.0 = icmp sge i8 %a, 0
%t.1 = icmp sle i8 %a, 4
%res.1 = xor i1 %t.0, %t.1
%c.0 = icmp sle i8 %a, 5
%res.2 = xor i1 %res.1, %c.0
ret i1 %res.2
else:
%c.2 = icmp sge i8 %a, 0
%c.3 = icmp sle i8 %a, 4
%res.3 = xor i1 %c.2, %c.3
%c.4 = icmp sle i8 %a, 5
%res.4 = xor i1 %res.3, %c.4
ret i1 %res.4
}
define i1 @uge_assumed_positive_values(i8 %a, i8 %b) {
; CHECK-LABEL: @uge_assumed_positive_values(
; CHECK-NEXT: [[A_UGT_B:%.*]] = icmp samesign uge i8 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: call void @llvm.assume(i1 [[A_UGT_B]])
; CHECK-NEXT: ret i1 true
;
%a_ugt_b = icmp samesign uge i8 %a, %b
call void @llvm.assume(i1 %a_ugt_b)
%result = icmp sge i8 %a, %b
ret i1 %result
}
define i1 @ugt_assumed_positive_values(i8 %a, i8 %b) {
; CHECK-LABEL: @ugt_assumed_positive_values(
; CHECK-NEXT: [[A_UGT_B:%.*]] = icmp samesign ugt i8 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: call void @llvm.assume(i1 [[A_UGT_B]])
; CHECK-NEXT: ret i1 true
;
%a_ugt_b = icmp samesign ugt i8 %a, %b
call void @llvm.assume(i1 %a_ugt_b)
%result = icmp sgt i8 %a, %b
ret i1 %result
}
define i1 @implied_condition_sgt_ugt(i8 %a, i8 %b) {
; CHECK-LABEL: @implied_condition_sgt_ugt(
; CHECK-NEXT: [[CMP_SGT:%.*]] = icmp sgt i8 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: br i1 [[CMP_SGT]], label [[GREATER:%.*]], label [[EXIT:%.*]]
; CHECK: greater:
; CHECK-NEXT: ret i1 true
; CHECK: exit:
; CHECK-NEXT: ret i1 false
;
%cmp_sgt = icmp sgt i8 %a, %b
br i1 %cmp_sgt, label %greater, label %exit
greater:
%cmp_ugt = icmp samesign ugt i8 %a, %b
ret i1 %cmp_ugt
exit:
ret i1 false
}
define i1 @implied_condition_sle_ule(i8 %a) {
; CHECK-LABEL: @implied_condition_sle_ule(
; CHECK-NEXT: [[CMP_SLE:%.*]] = icmp sle i8 [[A:%.*]], 42
; CHECK-NEXT: br i1 [[CMP_SLE]], label [[LESS_OR_EQUAL:%.*]], label [[EXIT:%.*]]
; CHECK: less_or_equal:
; CHECK-NEXT: ret i1 true
; CHECK: exit:
; CHECK-NEXT: ret i1 false
;
%cmp_sle = icmp sle i8 %a, 42
br i1 %cmp_sle, label %less_or_equal, label %exit
less_or_equal:
%cmp_ule = icmp samesign ule i8 %a, 42
ret i1 %cmp_ule
exit:
ret i1 false
}
define i1 @implied_condition_cannot_simplify(i8 %a, i8 %b) {
; CHECK-LABEL: @implied_condition_cannot_simplify(
; CHECK-NEXT: [[CMP_SGT:%.*]] = icmp ne i8 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: br i1 [[CMP_SGT]], label [[GREATER:%.*]], label [[EXIT:%.*]]
; CHECK: not_equal:
; CHECK-NEXT: [[CMP_UGT:%.*]] = icmp samesign ugt i8 [[A]], [[B]]
; CHECK-NEXT: ret i1 [[CMP_UGT]]
; CHECK: exit:
; CHECK-NEXT: ret i1 false
;
%cmp_ne = icmp ne i8 %a, %b
br i1 %cmp_ne, label %not_equal, label %exit
not_equal:
%cmp_ugt = icmp samesign ugt i8 %a, %b
ret i1 %cmp_ugt
exit:
ret i1 false
}