Revert r328119 "[InstCombine] add folds for xor-of-icmp signbit tests (PR36682)"

This asserts when compiling safe_numerics_unittest.cpp in Chromium with
MSan.

llvm-svn: 328145
This commit is contained in:
Reid Kleckner 2018-03-21 20:35:36 +00:00
parent c8d395a168
commit 762331be07
3 changed files with 29 additions and 54 deletions

View File

@ -2363,36 +2363,6 @@ Value *InstCombiner::foldXorOfICmps(ICmpInst *LHS, ICmpInst *RHS) {
}
}
// TODO: This can be generalized to compares of non-signbits using
// decomposeBitTestICmp(). It could be enhanced more by using (something like)
// foldLogOpOfMaskedICmps().
ICmpInst::Predicate PredL = LHS->getPredicate();
ICmpInst::Predicate PredR = RHS->getPredicate();
Value *LHS0 = LHS->getOperand(0), *LHS1 = LHS->getOperand(1);
Value *RHS0 = RHS->getOperand(0), *RHS1 = RHS->getOperand(1);
if ((LHS->hasOneUse() || RHS->hasOneUse()) && PredL == PredR) {
// (X > -1) ^ (Y > -1) --> (X ^ Y) < 0
// (X < 0) ^ (Y < 0) --> (X ^ Y) < 0
if ((match(LHS1, m_AllOnes()) && match(RHS1, m_AllOnes()) &&
PredL == CmpInst::ICMP_SGT) ||
(match(LHS1, m_Zero()) && match(RHS1, m_Zero()) &&
PredL == CmpInst::ICMP_SLT)) {
Value *Zero = ConstantInt::getNullValue(LHS0->getType());
return Builder.CreateICmpSLT(Builder.CreateXor(LHS0, RHS0), Zero);
}
}
if ((LHS->hasOneUse() || RHS->hasOneUse())) {
// (X > -1) ^ (Y < 0) --> (X ^ Y) > -1
// (X < 0) ^ (Y > -1) --> (X ^ Y) > -1
if ((match(LHS1, m_AllOnes()) && match(RHS1, m_Zero()) &&
PredL == CmpInst::ICMP_SGT && PredR == CmpInst::ICMP_SLT) ||
(match(LHS1, m_Zero()) && match(RHS1, m_AllOnes()) &&
PredL == CmpInst::ICMP_SLT && PredR == CmpInst::ICMP_SGT)) {
Value *MinusOne = ConstantInt::getAllOnesValue(LHS0->getType());
return Builder.CreateICmpSGT(Builder.CreateXor(LHS0, RHS0), MinusOne);
}
}
// Instead of trying to imitate the folds for and/or, decompose this 'xor'
// into those logic ops. That is, try to turn this into an and-of-icmps
// because we have many folds for that pattern.

View File

@ -1,14 +1,15 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -instcombine -S < %s | FileCheck %s
; PR5438
; TODO: This should also optimize down.
define i32 @test1(i32 %a, i32 %b) nounwind readnone {
; CHECK-LABEL: @test1(
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]
; CHECK-NEXT: [[DOTLOBIT:%.*]] = lshr i32 [[TMP1]], 31
; CHECK-NEXT: [[DOTLOBIT_NOT:%.*]] = xor i32 [[DOTLOBIT]], 1
; CHECK-NEXT: ret i32 [[DOTLOBIT_NOT]]
; CHECK-NEXT: [[T0:%.*]] = icmp sgt i32 [[A:%.*]], -1
; CHECK-NEXT: [[T1:%.*]] = icmp slt i32 [[B:%.*]], 0
; CHECK-NEXT: [[T2:%.*]] = xor i1 [[T1]], [[T0]]
; CHECK-NEXT: [[T3:%.*]] = zext i1 [[T2]] to i32
; CHECK-NEXT: ret i32 [[T3]]
;
%t0 = icmp sgt i32 %a, -1
%t1 = icmp slt i32 %b, 0
@ -35,7 +36,7 @@ define i32 @test2(i32 %a, i32 %b) nounwind readnone {
define i32 @test3(i32 %a, i32 %b) nounwind readnone {
; CHECK-LABEL: @test3(
; CHECK-NEXT: [[T2_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: [[T2_UNSHIFTED:%.*]] = xor i32 %a, %b
; CHECK-NEXT: [[T2_UNSHIFTED_LOBIT:%.*]] = lshr i32 [[T2_UNSHIFTED]], 31
; CHECK-NEXT: [[T2_UNSHIFTED_LOBIT_NOT:%.*]] = xor i32 [[T2_UNSHIFTED_LOBIT]], 1
; CHECK-NEXT: ret i32 [[T2_UNSHIFTED_LOBIT_NOT]]
@ -67,7 +68,7 @@ define <2 x i32> @test3vec(<2 x i32> %a, <2 x i32> %b) nounwind readnone {
; is one, not zero.
define i32 @test3i(i32 %a, i32 %b) nounwind readnone {
; CHECK-LABEL: @test3i(
; CHECK-NEXT: [[T01:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: [[T01:%.*]] = xor i32 %a, %b
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[T01]], 31
; CHECK-NEXT: [[T4:%.*]] = xor i32 [[TMP1]], 1
; CHECK-NEXT: ret i32 [[T4]]
@ -83,7 +84,7 @@ define i32 @test3i(i32 %a, i32 %b) nounwind readnone {
define i1 @test4a(i32 %a) {
; CHECK-LABEL: @test4a(
; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[A:%.*]], 1
; CHECK-NEXT: [[C:%.*]] = icmp slt i32 %a, 1
; CHECK-NEXT: ret i1 [[C]]
;
%l = ashr i32 %a, 31
@ -96,7 +97,7 @@ define i1 @test4a(i32 %a) {
define <2 x i1> @test4a_vec(<2 x i32> %a) {
; CHECK-LABEL: @test4a_vec(
; CHECK-NEXT: [[C:%.*]] = icmp slt <2 x i32> [[A:%.*]], <i32 1, i32 1>
; CHECK-NEXT: [[C:%.*]] = icmp slt <2 x i32> %a, <i32 1, i32 1>
; CHECK-NEXT: ret <2 x i1> [[C]]
;
%l = ashr <2 x i32> %a, <i32 31, i32 31>
@ -109,7 +110,7 @@ define <2 x i1> @test4a_vec(<2 x i32> %a) {
define i1 @test4b(i64 %a) {
; CHECK-LABEL: @test4b(
; CHECK-NEXT: [[C:%.*]] = icmp slt i64 [[A:%.*]], 1
; CHECK-NEXT: [[C:%.*]] = icmp slt i64 %a, 1
; CHECK-NEXT: ret i1 [[C]]
;
%l = ashr i64 %a, 63
@ -122,7 +123,7 @@ define i1 @test4b(i64 %a) {
define i1 @test4c(i64 %a) {
; CHECK-LABEL: @test4c(
; CHECK-NEXT: [[C:%.*]] = icmp slt i64 [[A:%.*]], 1
; CHECK-NEXT: [[C:%.*]] = icmp slt i64 %a, 1
; CHECK-NEXT: ret i1 [[C]]
;
%l = ashr i64 %a, 63
@ -136,7 +137,7 @@ define i1 @test4c(i64 %a) {
define <2 x i1> @test4c_vec(<2 x i64> %a) {
; CHECK-LABEL: @test4c_vec(
; CHECK-NEXT: [[C:%.*]] = icmp slt <2 x i64> [[A:%.*]], <i64 1, i64 1>
; CHECK-NEXT: [[C:%.*]] = icmp slt <2 x i64> %a, <i64 1, i64 1>
; CHECK-NEXT: ret <2 x i1> [[C]]
;
%l = ashr <2 x i64> %a, <i64 63, i64 63>

View File

@ -42,9 +42,10 @@ define i1 @eq_ne_zero(i4 %x, i4 %y) {
define i1 @slt_zero(i4 %x, i4 %y) {
; CHECK-LABEL: @slt_zero(
; CHECK-NEXT: [[TMP1:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i4 [[TMP1]], 0
; CHECK-NEXT: ret i1 [[TMP2]]
; CHECK-NEXT: [[I0:%.*]] = icmp slt i4 [[X:%.*]], 0
; CHECK-NEXT: [[I1:%.*]] = icmp slt i4 [[Y:%.*]], 0
; CHECK-NEXT: [[R:%.*]] = xor i1 [[I0]], [[I1]]
; CHECK-NEXT: ret i1 [[R]]
;
%i0 = icmp slt i4 %x, 0
%i1 = icmp slt i4 %y, 0
@ -67,9 +68,10 @@ define i1 @sgt_zero(i4 %x, i4 %y) {
define i1 @sgt_minus1(i4 %x, i4 %y) {
; CHECK-LABEL: @sgt_minus1(
; CHECK-NEXT: [[TMP1:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i4 [[TMP1]], 0
; CHECK-NEXT: ret i1 [[TMP2]]
; CHECK-NEXT: [[I0:%.*]] = icmp sgt i4 [[X:%.*]], -1
; CHECK-NEXT: [[I1:%.*]] = icmp sgt i4 [[Y:%.*]], -1
; CHECK-NEXT: [[R:%.*]] = xor i1 [[I0]], [[I1]]
; CHECK-NEXT: ret i1 [[R]]
;
%i0 = icmp sgt i4 %x, -1
%i1 = icmp sgt i4 %y, -1
@ -79,9 +81,10 @@ define i1 @sgt_minus1(i4 %x, i4 %y) {
define i1 @slt_zero_sgt_minus1(i4 %x, i4 %y) {
; CHECK-LABEL: @slt_zero_sgt_minus1(
; CHECK-NEXT: [[TMP1:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i4 [[TMP1]], -1
; CHECK-NEXT: ret i1 [[TMP2]]
; CHECK-NEXT: [[I0:%.*]] = icmp slt i4 [[X:%.*]], 0
; CHECK-NEXT: [[I1:%.*]] = icmp sgt i4 [[Y:%.*]], -1
; CHECK-NEXT: [[R:%.*]] = xor i1 [[I0]], [[I1]]
; CHECK-NEXT: ret i1 [[R]]
;
%i0 = icmp slt i4 %x, 0
%i1 = icmp sgt i4 %y, -1
@ -91,9 +94,10 @@ define i1 @slt_zero_sgt_minus1(i4 %x, i4 %y) {
define <2 x i1> @sgt_minus1_slt_zero_sgt(<2 x i4> %x, <2 x i4> %y) {
; CHECK-LABEL: @sgt_minus1_slt_zero_sgt(
; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i4> [[Y:%.*]], [[X:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt <2 x i4> [[TMP1]], <i4 -1, i4 -1>
; CHECK-NEXT: ret <2 x i1> [[TMP2]]
; CHECK-NEXT: [[I1:%.*]] = icmp sgt <2 x i4> [[X:%.*]], <i4 -1, i4 -1>
; CHECK-NEXT: [[I0:%.*]] = icmp slt <2 x i4> [[Y:%.*]], zeroinitializer
; CHECK-NEXT: [[R:%.*]] = xor <2 x i1> [[I0]], [[I1]]
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%i1 = icmp sgt <2 x i4> %x, <i4 -1, i4 -1>
%i0 = icmp slt <2 x i4> %y, zeroinitializer