From 3034c106753595f564d5852a2d4398f0acb16b32 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 17 Jun 2009 01:22:39 +0000 Subject: [PATCH] Fix ScalarEvolution's Xor handling to not assume that an And that gets recognized with a SCEVZeroExtendExpr must be an And with a low-bits mask. With r73540, this is no longer the case. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73594 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ScalarEvolution.cpp | 9 ++++++--- test/Analysis/ScalarEvolution/xor-and.ll | 11 +++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 test/Analysis/ScalarEvolution/xor-and.ll diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index 3731fdfc712..2546e81952b 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -2453,9 +2453,12 @@ SCEVHandle ScalarEvolution::createSCEV(Value *V) { if (BO->getOpcode() == Instruction::And && LCI->getValue() == CI->getValue()) if (const SCEVZeroExtendExpr *Z = - dyn_cast(getSCEV(U->getOperand(0)))) - return getZeroExtendExpr(getNotSCEV(Z->getOperand()), - U->getType()); + dyn_cast(getSCEV(U->getOperand(0)))) { + SCEVHandle ZO = Z->getOperand(); + if (APIntOps::isMask(getTypeSizeInBits(ZO->getType()), + CI->getValue())) + return getZeroExtendExpr(getNotSCEV(ZO), U->getType()); + } } break; diff --git a/test/Analysis/ScalarEvolution/xor-and.ll b/test/Analysis/ScalarEvolution/xor-and.ll new file mode 100644 index 00000000000..9b02bb803ff --- /dev/null +++ b/test/Analysis/ScalarEvolution/xor-and.ll @@ -0,0 +1,11 @@ +; RUN: llvm-as < %s | opt -scalar-evolution -disable-output -analyze | grep {\\--> %z} + +; ScalarEvolution shouldn't try to analyze %s into something like +; --> (zext i4 (-1 + (-1 * (trunc i64 (8 * %x) to i4))) to i64) + +define i64 @foo(i64 %x) { + %a = shl i64 %x, 3 + %t = and i64 %a, 8 + %z = xor i64 %t, 8 + ret i64 %z +}