From 865866e7fef0370158e09d6bfc8ff6bcfad8ac70 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. llvm-svn: 132097 --- .../InstCombine/InstCombineCompares.cpp | 8 ++++---- llvm/test/Transforms/InstCombine/exact.ll | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index c2b9e71c6f28..c7ed098cbf88 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/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/llvm/test/Transforms/InstCombine/exact.ll b/llvm/test/Transforms/InstCombine/exact.ll index 58f8b5d5bcd8..14741e3c1c33 100644 --- a/llvm/test/Transforms/InstCombine/exact.ll +++ b/llvm/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 {