diff options
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 14 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/icmp-xor-signbit.ll | 16 |
2 files changed, 13 insertions, 17 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 6492eaedae9..fed67780e0f 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -3030,18 +3030,21 @@ Instruction *InstCombiner::foldICmpBinOp(ICmpInst &I) { break; case Instruction::Add: case Instruction::Sub: - case Instruction::Xor: + case Instruction::Xor: { if (I.isEquality()) // a+x icmp eq/ne b+x --> a icmp b return new ICmpInst(Pred, BO0->getOperand(0), BO1->getOperand(0)); - // icmp u/s (a ^ signmask), (b ^ signmask) --> icmp s/u a, b - if (ConstantInt *CI = dyn_cast<ConstantInt>(BO0->getOperand(1))) { - if (CI->getValue().isSignMask()) { + + const APInt *C; + if (match(BO0->getOperand(1), m_APInt(C))) { + // icmp u/s (a ^ signmask), (b ^ signmask) --> icmp s/u a, b + if (C->isSignMask()) { ICmpInst::Predicate NewPred = I.isSigned() ? I.getUnsignedPredicate() : I.getSignedPredicate(); return new ICmpInst(NewPred, BO0->getOperand(0), BO1->getOperand(0)); } - if (BO0->getOpcode() == Instruction::Xor && CI->isMaxValue(true)) { + // icmp u/s (a ^ maxsignval), (b ^ maxsignval) --> icmp s/u' a, b + if (BO0->getOpcode() == Instruction::Xor && C->isMaxSignedValue()) { ICmpInst::Predicate NewPred = I.isSigned() ? I.getUnsignedPredicate() : I.getSignedPredicate(); NewPred = I.getSwappedPredicate(NewPred); @@ -3049,6 +3052,7 @@ Instruction *InstCombiner::foldICmpBinOp(ICmpInst &I) { } } break; + } case Instruction::Mul: if (!I.isEquality()) break; diff --git a/llvm/test/Transforms/InstCombine/icmp-xor-signbit.ll b/llvm/test/Transforms/InstCombine/icmp-xor-signbit.ll index 4b4d1ddbc5a..548d1232bb8 100644 --- a/llvm/test/Transforms/InstCombine/icmp-xor-signbit.ll +++ b/llvm/test/Transforms/InstCombine/icmp-xor-signbit.ll @@ -18,9 +18,7 @@ define i1 @slt_to_ult(i8 %x, i8 %y) { define <2 x i1> @slt_to_ult_splat(<2 x i8> %x, <2 x i8> %y) { ; CHECK-LABEL: @slt_to_ult_splat( -; CHECK-NEXT: [[A:%.*]] = xor <2 x i8> %x, <i8 -128, i8 -128> -; CHECK-NEXT: [[B:%.*]] = xor <2 x i8> %y, <i8 -128, i8 -128> -; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A]], [[B]] +; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> %x, %y ; CHECK-NEXT: ret <2 x i1> [[CMP]] ; %a = xor <2 x i8> %x, <i8 128, i8 128> @@ -44,9 +42,7 @@ define i1 @ult_to_slt(i8 %x, i8 %y) { define <2 x i1> @ult_to_slt_splat(<2 x i8> %x, <2 x i8> %y) { ; CHECK-LABEL: @ult_to_slt_splat( -; CHECK-NEXT: [[A:%.*]] = xor <2 x i8> %x, <i8 -128, i8 -128> -; CHECK-NEXT: [[B:%.*]] = xor <2 x i8> %y, <i8 -128, i8 -128> -; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> [[A]], [[B]] +; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> %x, %y ; CHECK-NEXT: ret <2 x i1> [[CMP]] ; %a = xor <2 x i8> %x, <i8 128, i8 128> @@ -70,9 +66,7 @@ define i1 @slt_to_ugt(i8 %x, i8 %y) { define <2 x i1> @slt_to_ugt_splat(<2 x i8> %x, <2 x i8> %y) { ; CHECK-LABEL: @slt_to_ugt_splat( -; CHECK-NEXT: [[A:%.*]] = xor <2 x i8> %x, <i8 127, i8 127> -; CHECK-NEXT: [[B:%.*]] = xor <2 x i8> %y, <i8 127, i8 127> -; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A]], [[B]] +; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i8> %x, %y ; CHECK-NEXT: ret <2 x i1> [[CMP]] ; %a = xor <2 x i8> %x, <i8 127, i8 127> @@ -96,9 +90,7 @@ define i1 @ult_to_sgt(i8 %x, i8 %y) { define <2 x i1> @ult_to_sgt_splat(<2 x i8> %x, <2 x i8> %y) { ; CHECK-LABEL: @ult_to_sgt_splat( -; CHECK-NEXT: [[A:%.*]] = xor <2 x i8> %x, <i8 127, i8 127> -; CHECK-NEXT: [[B:%.*]] = xor <2 x i8> %y, <i8 127, i8 127> -; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> [[A]], [[B]] +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> %x, %y ; CHECK-NEXT: ret <2 x i1> [[CMP]] ; %a = xor <2 x i8> %x, <i8 127, i8 127> |

