From 05c1d372b770f812930915663e4fd8e315234808 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 27 Apr 2009 01:41:10 +0000 Subject: [PATCH] Handle ands with ~0 correctly too. This fixes PR4052. llvm-svn: 70176 --- llvm/lib/Analysis/ScalarEvolution.cpp | 2 + .../Transforms/IndVarSimplify/avoid-i0.ll | 103 ++++++++++++++++++ 2 files changed, 105 insertions(+) diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 495290d8d731..a9521bb581ed 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -1756,6 +1756,8 @@ SCEVHandle ScalarEvolution::createSCEV(Value *V) { if (ConstantInt *CI = dyn_cast(U->getOperand(1))) { if (CI->isNullValue()) return getSCEV(U->getOperand(1)); + if (CI->isAllOnesValue()) + return getSCEV(U->getOperand(0)); const APInt &A = CI->getValue(); unsigned Ones = A.countTrailingOnes(); if (APIntOps::isMask(Ones, A)) diff --git a/llvm/test/Transforms/IndVarSimplify/avoid-i0.ll b/llvm/test/Transforms/IndVarSimplify/avoid-i0.ll index 28112e75f556..3456bd3d6c9c 100644 --- a/llvm/test/Transforms/IndVarSimplify/avoid-i0.ll +++ b/llvm/test/Transforms/IndVarSimplify/avoid-i0.ll @@ -1,4 +1,5 @@ ; RUN: llvm-as < %s | opt -indvars +; PR4052 ; PR4054 ; Don't treat an and with 0 as a mask (trunc+zext). @@ -21,3 +22,105 @@ bb6: ; preds = %bb4 %0 = and i8 0, 0 ; [#uses=1] br label %bb } + +@x = common global i32 0 ; [#uses=1] + +define signext i8 @safe_sub_func_int32_t_s_s(i32 %_si1, i8 signext %_si2) nounwind { +entry: + %_si1_addr = alloca i32 ; [#uses=3] + %_si2_addr = alloca i8 ; [#uses=3] + %retval = alloca i32 ; [#uses=2] + %0 = alloca i32 ; [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store i32 %_si1, i32* %_si1_addr + store i8 %_si2, i8* %_si2_addr + %1 = load i8* %_si2_addr, align 1 ; [#uses=1] + %2 = sext i8 %1 to i32 ; [#uses=1] + %3 = load i32* %_si1_addr, align 4 ; [#uses=1] + %4 = xor i32 %2, %3 ; [#uses=1] + %5 = load i8* %_si2_addr, align 1 ; [#uses=1] + %6 = sext i8 %5 to i32 ; [#uses=1] + %7 = sub i32 7, %6 ; [#uses=1] + %8 = load i32* %_si1_addr, align 4 ; [#uses=1] + %9 = shl i32 %8, %7 ; [#uses=1] + %10 = and i32 %4, %9 ; [#uses=1] + %11 = icmp slt i32 %10, 0 ; [#uses=1] + %12 = zext i1 %11 to i32 ; [#uses=1] + store i32 %12, i32* %0, align 4 + %13 = load i32* %0, align 4 ; [#uses=1] + store i32 %13, i32* %retval, align 4 + br label %return + +return: ; preds = %entry + %retval1 = load i32* %retval ; [#uses=1] + %retval12 = trunc i32 %retval1 to i8 ; [#uses=1] + ret i8 %retval12 +} + +define i32 @safe_sub_func_uint64_t_u_u(i32 %_ui1, i32 %_ui2) nounwind { +entry: + %_ui1_addr = alloca i32 ; [#uses=2] + %_ui2_addr = alloca i32 ; [#uses=1] + %retval = alloca i32 ; [#uses=2] + %0 = alloca i32 ; [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store i32 %_ui1, i32* %_ui1_addr + store i32 %_ui2, i32* %_ui2_addr + %1 = load i32* %_ui1_addr, align 4 ; [#uses=1] + %2 = sub i32 %1, 1 ; [#uses=1] + store i32 %2, i32* %0, align 4 + %3 = load i32* %0, align 4 ; [#uses=1] + store i32 %3, i32* %retval, align 4 + br label %return + +return: ; preds = %entry + %retval1 = load i32* %retval ; [#uses=1] + ret i32 %retval1 +} + +define void @int87(i8 signext %p_48, i8 signext %p_49) nounwind { +entry: + %p_48_addr = alloca i8 ; [#uses=1] + %p_49_addr = alloca i8 ; [#uses=1] + %l_52 = alloca i32 ; [#uses=7] + %vol.0 = alloca i32 ; [#uses=1] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store i8 %p_48, i8* %p_48_addr + store i8 %p_49, i8* %p_49_addr + br label %bb4 + +bb: ; preds = %bb4 + %0 = volatile load i32* @x, align 4 ; [#uses=1] + store i32 %0, i32* %vol.0, align 4 + store i32 0, i32* %l_52, align 4 + br label %bb2 + +bb1: ; preds = %bb2 + %1 = load i32* %l_52, align 4 ; [#uses=1] + %2 = call i32 @safe_sub_func_uint64_t_u_u(i32 %1, i32 1) nounwind ; [#uses=1] + store i32 %2, i32* %l_52, align 4 + br label %bb2 + +bb2: ; preds = %bb1, %bb + %3 = load i32* %l_52, align 4 ; [#uses=1] + %4 = icmp eq i32 %3, 0 ; [#uses=1] + br i1 %4, label %bb1, label %bb3 + +bb3: ; preds = %bb2 + %5 = load i32* %l_52, align 4 ; [#uses=1] + %6 = call signext i8 @safe_sub_func_int32_t_s_s(i32 %5, i8 signext 1) nounwind ; [#uses=1] + %7 = sext i8 %6 to i32 ; [#uses=1] + store i32 %7, i32* %l_52, align 4 + br label %bb4 + +bb4: ; preds = %bb3, %entry + %8 = load i32* %l_52, align 4 ; [#uses=1] + %9 = icmp ne i32 %8, 0 ; [#uses=1] + br i1 %9, label %bb, label %bb5 + +bb5: ; preds = %bb4 + br label %return + +return: ; preds = %bb5 + ret void +}