From a831a9b972f1b4fa4f3457acf303abbfc71c1ede Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Wed, 25 May 2011 23:26:20 +0000 Subject: [PATCH] PR9998: ashr exact %x, 31 is not equivalent to sdiv exact %x, -2147483648. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132097 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstCombineCompares.cpp | 8 ++++---- test/Transforms/InstCombine/exact.ll | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp index c2b9e71c6f2..c7ed098cbf8 100644 --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -919,11 +919,11 @@ Instruction *InstCombiner::FoldICmpShrCst(ICmpInst &ICI, BinaryOperator *Shr, if (ICI.isSigned() != (Shr->getOpcode() == Instruction::AShr)) return 0; - // Otherwise, all lshr and all exact ashr's are equivalent to a udiv/sdiv by - // a power of 2. Since we already have logic to simplify these, transform - // to div and then simplify the resultant comparison. + // Otherwise, all lshr and most exact ashr's are equivalent to a udiv/sdiv + // by a power of 2. Since we already have logic to simplify these, + // transform to div and then simplify the resultant comparison. if (Shr->getOpcode() == Instruction::AShr && - !Shr->isExact()) + (!Shr->isExact() || ShAmtVal == TypeBits - 1)) return 0; // Revisit the shift (to delete it). diff --git a/test/Transforms/InstCombine/exact.ll b/test/Transforms/InstCombine/exact.ll index 58f8b5d5bcd..14741e3c1c3 100644 --- a/test/Transforms/InstCombine/exact.ll +++ b/test/Transforms/InstCombine/exact.ll @@ -96,6 +96,22 @@ define i1 @ashr_icmp2(i64 %X) nounwind { ret i1 %Z } +; PR9998 +; Make sure we don't transform the ashr here into an sdiv +; CHECK: @pr9998 +; CHECK: = and i32 %V, 1 +; CHECK: %Z = icmp ne +; CHECK: ret i1 %Z +define i1 @pr9998(i32 %V) nounwind { +entry: + %W = shl i32 %V, 31 + %X = ashr exact i32 %W, 31 + %Y = sext i32 %X to i64 + %Z = icmp ugt i64 %Y, 7297771788697658747 + ret i1 %Z +} + + ; CHECK: @udiv_icmp1 ; CHECK: icmp ne i64 %X, 0 define i1 @udiv_icmp1(i64 %X) nounwind { -- 2.34.1