; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
define i1 @icmp_equality_test(i64 %X, i64 %Y, i64 %Z) {
; CHECK-LABEL: @icmp_equality_test(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[XEQY:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[XEQY]]
;
entry:
%XeqZ = icmp eq i64 %X, %Z
%YeqZ = icmp eq i64 %Y, %Z
%XeqY = icmp eq i64 %X, %Y
%not.YeqZ = xor i1 %YeqZ, true
%and = select i1 %not.YeqZ, i1 %XeqY, i1 false
%equal = select i1 %XeqZ, i1 %YeqZ, i1 %and
ret i1 %equal
}
define i1 @icmp_equality_test_constant(i42 %X, i42 %Y) {
; CHECK-LABEL: @icmp_equality_test_constant(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[XEQY:%.*]] = icmp eq i42 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[XEQY]]
;
entry:
%XeqC = icmp eq i42 %X, -42
%YeqC = icmp eq i42 %Y, -42
%XeqY = icmp eq i42 %X, %Y
%not.YeqC = xor i1 %YeqC, true
%and = select i1 %not.YeqC, i1 %XeqY, i1 false
%equal = select i1 %XeqC, i1 %YeqC, i1 %and
ret i1 %equal
}
define i1 @icmp_equality_test_swift_optional_pointers(i64 %X, i64 %Y) {
; CHECK-LABEL: @icmp_equality_test_swift_optional_pointers(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[XEQY:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[XEQY]]
;
entry:
%XeqC = icmp eq i64 %X, 0
%YeqC = icmp eq i64 %Y, 0
%either = select i1 %XeqC, i1 true, i1 %YeqC
%both = select i1 %XeqC, i1 %YeqC, i1 false
%XeqY = icmp eq i64 %X, %Y
%equal = select i1 %either, i1 %both, i1 %XeqY
ret i1 %equal
}
define <2 x i1> @icmp_equality_test_vector(<2 x i64> %X, <2 x i64> %Y) {
; CHECK-LABEL: @icmp_equality_test_vector(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[XEQY:%.*]] = icmp eq <2 x i64> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret <2 x i1> [[XEQY]]
;
entry:
%XeqC = icmp eq <2 x i64> %X, <i64 123, i64 456>
%YeqC = icmp eq <2 x i64> %Y, <i64 123, i64 456>
%XeqY = icmp eq <2 x i64> %X, %Y
%not.YeqC = xor <2 x i1> %YeqC, <i1 true, i1 true>
%and = select <2 x i1> %not.YeqC, <2 x i1> %XeqY, <2 x i1> <i1 false, i1 false>
%equal = select <2 x i1> %XeqC, <2 x i1> %YeqC, <2 x i1> %and
ret <2 x i1> %equal
}
define i1 @icmp_equality_test_commute_icmp1(i64 %X, i64 %Y, i64 %Z) {
; CHECK-LABEL: @icmp_equality_test_commute_icmp1(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[XEQY:%.*]] = icmp eq i64 [[Y:%.*]], [[X:%.*]]
; CHECK-NEXT: ret i1 [[XEQY]]
;
entry:
%XeqZ = icmp eq i64 %Z, %X
%YeqZ = icmp eq i64 %Z, %Y
%XeqY = icmp eq i64 %Y, %X
%not.YeqZ = xor i1 %YeqZ, true
%and = select i1 %not.YeqZ, i1 %XeqY, i1 false
%equal = select i1 %XeqZ, i1 %YeqZ, i1 %and
ret i1 %equal
}
define i1 @icmp_equality_test_commute_icmp2(i64 %X, i64 %Y, i64 %Z) {
; CHECK-LABEL: @icmp_equality_test_commute_icmp2(
; CHECK-NEXT: [[XEQY:%.*]] = icmp eq i64 [[Y:%.*]], [[X:%.*]]
; CHECK-NEXT: ret i1 [[XEQY]]
;
%XeqZ = icmp eq i64 %Z, %X
%YeqZ = icmp eq i64 %Y, %Z
%XeqY = icmp eq i64 %Y, %X
%not.YeqZ = xor i1 %YeqZ, true
%and = select i1 %not.YeqZ, i1 %XeqY, i1 false
%equal = select i1 %XeqZ, i1 %YeqZ, i1 %and
ret i1 %equal
}
define i1 @icmp_equality_test_commute_select1(i64 %X, i64 %Y, i64 %Z) {
; CHECK-LABEL: @icmp_equality_test_commute_select1(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[XEQY:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[XEQY]]
;
entry:
%XeqZ = icmp eq i64 %X, %Z
%YeqZ = icmp eq i64 %Y, %Z
%XeqY = icmp eq i64 %X, %Y
%and = select i1 %YeqZ, i1 false, i1 %XeqY
%equal = select i1 %XeqZ, i1 %YeqZ, i1 %and
ret i1 %equal
}
define i1 @icmp_equality_test_commute_select2(i64 %X, i64 %Y, i64 %Z) {
; CHECK-LABEL: @icmp_equality_test_commute_select2(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[XEQY:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[XEQY]]
;
entry:
%XeqZ = icmp eq i64 %X, %Z
%YeqZ = icmp eq i64 %Y, %Z
%XeqY = icmp eq i64 %X, %Y
%not.XeqZ = xor i1 %XeqZ, true
%and = select i1 %YeqZ, i1 false, i1 %XeqY
%equal = select i1 %not.XeqZ, i1 %and, i1 %YeqZ
ret i1 %equal
}
; Negative tests below
define i1 @icmp_equality_test_wrong_constant(i64 %X, i64 %Y) {
; CHECK-LABEL: @icmp_equality_test_wrong_constant(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[XEQC:%.*]] = icmp eq i64 [[X:%.*]], 0
; CHECK-NEXT: [[YEQC:%.*]] = icmp eq i64 [[Y:%.*]], 999
; CHECK-NEXT: [[XEQY:%.*]] = icmp eq i64 [[X]], [[Y]]
; CHECK-NEXT: [[NOT_YEQC:%.*]] = xor i1 [[YEQC]], true
; CHECK-NEXT: [[AND:%.*]] = select i1 [[NOT_YEQC]], i1 [[XEQY]], i1 false
; CHECK-NEXT: [[EQUAL:%.*]] = select i1 [[XEQC]], i1 [[YEQC]], i1 [[AND]]
; CHECK-NEXT: ret i1 [[EQUAL]]
;
entry:
%XeqC = icmp eq i64 %X, 0
%YeqC = icmp eq i64 %Y, 999
%XeqY = icmp eq i64 %X, %Y
%not.YeqC = xor i1 %YeqC, true
%and = select i1 %not.YeqC, i1 %XeqY, i1 false
%equal = select i1 %XeqC, i1 %YeqC, i1 %and
ret i1 %equal
}
define i1 @icmp_equality_test_missing_not(i64 %X, i64 %Y, i64 %Z) {
; CHECK-LABEL: @icmp_equality_test_missing_not(
; CHECK-NEXT: [[XEQZ:%.*]] = icmp eq i64 [[X:%.*]], [[Z:%.*]]
; CHECK-NEXT: [[YEQZ:%.*]] = icmp eq i64 [[Y:%.*]], [[Z]]
; CHECK-NEXT: [[XEQY:%.*]] = icmp eq i64 [[X]], [[Y]]
; CHECK-NEXT: [[AND:%.*]] = select i1 [[YEQZ]], i1 [[XEQY]], i1 false
; CHECK-NEXT: [[EQUAL:%.*]] = select i1 [[XEQZ]], i1 [[YEQZ]], i1 [[AND]]
; CHECK-NEXT: ret i1 [[EQUAL]]
;
%XeqZ = icmp eq i64 %X, %Z
%YeqZ = icmp eq i64 %Y, %Z
%XeqY = icmp eq i64 %X, %Y
%and = select i1 %YeqZ, i1 %XeqY, i1 false
%equal = select i1 %XeqZ, i1 %YeqZ, i1 %and
ret i1 %equal
}
define i1 @icmp_equality_test_wrong_and(i64 %X, i64 %Y, i64 %Z) {
; CHECK-LABEL: @icmp_equality_test_wrong_and(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[XEQZ:%.*]] = icmp eq i64 [[X:%.*]], [[Z:%.*]]
; CHECK-NEXT: [[YEQZ:%.*]] = icmp eq i64 [[Y:%.*]], [[Z]]
; CHECK-NEXT: [[XEQY:%.*]] = icmp eq i64 [[X]], [[Y]]
; CHECK-NEXT: [[AND:%.*]] = select i1 [[YEQZ]], i1 [[XEQY]], i1 false
; CHECK-NEXT: [[EQUAL:%.*]] = select i1 [[XEQZ]], i1 [[YEQZ]], i1 [[AND]]
; CHECK-NEXT: ret i1 [[EQUAL]]
;
entry:
%XeqZ = icmp eq i64 %X, %Z
%YeqZ = icmp eq i64 %Y, %Z
%XeqY = icmp eq i64 %X, %Y
%not.YeqZ = xor i1 %YeqZ, true
%and = select i1 %not.YeqZ, i1 false, i1 %XeqY
%equal = select i1 %XeqZ, i1 %YeqZ, i1 %and
ret i1 %equal
}
define i1 @icmp_equality_test_wrong_cmp(i64 %X, i64 %Y, i64 %Z) {
; CHECK-LABEL: @icmp_equality_test_wrong_cmp(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[XEQZ:%.*]] = icmp eq i64 [[X:%.*]], [[Z:%.*]]
; CHECK-NEXT: [[YEQZ:%.*]] = icmp eq i64 [[Y:%.*]], [[Z]]
; CHECK-NEXT: [[XEQY:%.*]] = icmp eq i64 [[X]], 999
; CHECK-NEXT: [[NOT_YEQZ:%.*]] = xor i1 [[YEQZ]], true
; CHECK-NEXT: [[AND:%.*]] = select i1 [[NOT_YEQZ]], i1 [[XEQY]], i1 false
; CHECK-NEXT: [[EQUAL:%.*]] = select i1 [[XEQZ]], i1 [[YEQZ]], i1 [[AND]]
; CHECK-NEXT: ret i1 [[EQUAL]]
;
entry:
%XeqZ = icmp eq i64 %X, %Z
%YeqZ = icmp eq i64 %Y, %Z
%XeqY = icmp eq i64 %X, 999
%not.YeqZ = xor i1 %YeqZ, true
%and = select i1 %not.YeqZ, i1 %XeqY, i1 false
%equal = select i1 %XeqZ, i1 %YeqZ, i1 %and
ret i1 %equal
}
define i1 @icmp_equality_test_wrong_equal(i64 %X, i64 %Y, i64 %Z) {
; CHECK-LABEL: @icmp_equality_test_wrong_equal(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[XEQZ:%.*]] = icmp eq i64 [[X:%.*]], [[Z:%.*]]
; CHECK-NEXT: [[YEQZ:%.*]] = icmp eq i64 [[Y:%.*]], [[Z]]
; CHECK-NEXT: [[XEQY:%.*]] = icmp eq i64 [[X]], [[Y]]
; CHECK-NEXT: [[NOT_YEQZ:%.*]] = xor i1 [[YEQZ]], true
; CHECK-NEXT: [[AND:%.*]] = select i1 [[NOT_YEQZ]], i1 [[XEQY]], i1 false
; CHECK-NEXT: [[EQUAL:%.*]] = select i1 [[XEQZ]], i1 [[AND]], i1 [[YEQZ]]
; CHECK-NEXT: ret i1 [[EQUAL]]
;
entry:
%XeqZ = icmp eq i64 %X, %Z
%YeqZ = icmp eq i64 %Y, %Z
%XeqY = icmp eq i64 %X, %Y
%not.YeqZ = xor i1 %YeqZ, true
%and = select i1 %not.YeqZ, i1 %XeqY, i1 false
%equal = select i1 %XeqZ, i1 %and, i1 %YeqZ
ret i1 %equal
}