From: Davide Italiano Date: Tue, 22 Nov 2016 22:11:25 +0000 (+0000) Subject: [SCCP] Remove code in visitBinaryOperator (and add tests). X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4f6508063794e429ef087a36a401623695f66cbf;p=llvm [SCCP] Remove code in visitBinaryOperator (and add tests). We visit and/or, we try to derive a lattice value for the instruction even if one of the operands is overdefined. If the non-overdefined value is still 'unknown' just return and wait for ResolvedUndefsIn to "plug in" the correct value. This simplifies the logic a bit. While I'm here add tests for missing cases. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@287709 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index eeb36bb56a1..9de3059dadf 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -928,25 +928,17 @@ void SCCPSolver::visitBinaryOperator(Instruction &I) { NonOverdefVal = &V2State; if (NonOverdefVal) { - if (NonOverdefVal->isUnknown()) { - // Could annihilate value. - if (I.getOpcode() == Instruction::And) - markConstant(IV, &I, Constant::getNullValue(I.getType())); - else if (VectorType *PT = dyn_cast(I.getType())) - markConstant(IV, &I, Constant::getAllOnesValue(PT)); - else - markConstant(IV, &I, - Constant::getAllOnesValue(I.getType())); + if (NonOverdefVal->isUnknown()) return; - } if (I.getOpcode() == Instruction::And) { // X and 0 = 0 if (NonOverdefVal->getConstant()->isNullValue()) return markConstant(IV, &I, NonOverdefVal->getConstant()); } else { + // X or -1 = -1 if (ConstantInt *CI = NonOverdefVal->getConstantInt()) - if (CI->isAllOnesValue()) // X or -1 = -1 + if (CI->isAllOnesValue()) return markConstant(IV, &I, NonOverdefVal->getConstant()); } } diff --git a/test/Transforms/SCCP/logical-nuke.ll b/test/Transforms/SCCP/logical-nuke.ll index 45f6f44a0eb..4ef52a25539 100644 --- a/test/Transforms/SCCP/logical-nuke.ll +++ b/test/Transforms/SCCP/logical-nuke.ll @@ -1,9 +1,31 @@ -; RUN: opt < %s -sccp -S | grep "ret i32 0" +; RUN: opt < %s -sccp -S | FileCheck %s ; Test that SCCP has basic knowledge of when and/or nuke overdefined values. -define i32 @test(i32 %X) { - %Y = and i32 %X, 0 ; [#uses=1] - ret i32 %Y +; CHECK-LABEL: test +; CHECK: ret i32 0 + define i32 @test(i32 %X) { + %Y = and i32 %X, 0 + ret i32 %Y } +; CHECK-LABEL: test2 +; CHECK: ret i32 -1 +define i32 @test2(i32 %X) { + %Y = or i32 -1, %X + ret i32 %Y +} + +; CHECK-LABEL: test3 +; CHECK: ret i32 0 +define i32 @test3(i32 %X) { + %Y = and i32 undef, %X + ret i32 %Y +} + +; CHECK-LABEL: test4 +; CHECK: ret i32 -1 +define i32 @test4(i32 %X) { + %Y = or i32 %X, undef + ret i32 %Y +}