From 89f9af5487e3287c1638e53d0b5b057154eb1b32 Mon Sep 17 00:00:00 2001 From: Cameron McInally Date: Mon, 3 Jun 2019 21:53:56 +0000 Subject: [PATCH] [SCCP] Add UnaryOperator visitor to SCCP for unary FNeg Differential Revision: https://reviews.llvm.org/D62819 llvm-svn: 362449 --- llvm/lib/Transforms/Scalar/SCCP.cpp | 26 ++++++++++++++++++++ llvm/test/Transforms/SCCP/apfloat-basictest.ll | 33 ++++++++++++++++++++++++++ llvm/test/Transforms/SCCP/undef-resolve.ll | 8 +++++++ 3 files changed, 67 insertions(+) create mode 100644 llvm/test/Transforms/SCCP/apfloat-basictest.ll diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp index 66885ed..1d0354b 100644 --- a/llvm/lib/Transforms/Scalar/SCCP.cpp +++ b/llvm/lib/Transforms/Scalar/SCCP.cpp @@ -613,6 +613,7 @@ private: void visitCastInst(CastInst &I); void visitSelectInst(SelectInst &I); + void visitUnaryOperator(Instruction &I); void visitBinaryOperator(Instruction &I); void visitCmpInst(CmpInst &I); void visitExtractValueInst(ExtractValueInst &EVI); @@ -969,6 +970,29 @@ void SCCPSolver::visitSelectInst(SelectInst &I) { markOverdefined(&I); } +// Handle Unary Operators. +void SCCPSolver::visitUnaryOperator(Instruction &I) { + LatticeVal V0State = getValueState(I.getOperand(0)); + + LatticeVal &IV = ValueState[&I]; + if (IV.isOverdefined()) return; + + if (V0State.isConstant()) { + Constant *C = ConstantExpr::get(I.getOpcode(), V0State.getConstant()); + + // op Y -> undef. + if (isa(C)) + return; + return (void)markConstant(IV, &I, C); + } + + // If something is undef, wait for it to resolve. + if (!V0State.isOverdefined()) + return; + + markOverdefined(&I); +} + // Handle Binary Operators. void SCCPSolver::visitBinaryOperator(Instruction &I) { LatticeVal V1State = getValueState(I.getOperand(0)); @@ -1484,6 +1508,8 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) { else markOverdefined(&I); return true; + case Instruction::FNeg: + break; // fneg undef -> undef case Instruction::ZExt: case Instruction::SExt: case Instruction::FPToUI: diff --git a/llvm/test/Transforms/SCCP/apfloat-basictest.ll b/llvm/test/Transforms/SCCP/apfloat-basictest.ll new file mode 100644 index 0000000..2ef0966 --- /dev/null +++ b/llvm/test/Transforms/SCCP/apfloat-basictest.ll @@ -0,0 +1,33 @@ +; This is a basic sanity check for constant propagation. The fneg instruction +; should be eliminated. + +; RUN: opt < %s -sccp -S | FileCheck %s + +define double @test(i1 %B) { + br i1 %B, label %BB1, label %BB2 +BB1: + %Val = fneg double 42.0 + br label %BB3 +BB2: + br label %BB3 +BB3: + %Ret = phi double [%Val, %BB1], [1.0, %BB2] + ret double %Ret +; CHECK-LABEL: @test( +; CHECK: [[PHI:%.*]] = phi double [ -4.200000e+01, %BB1 ], [ 1.000000e+00, %BB2 ] +} + +define double @test1(i1 %B) { + br i1 %B, label %BB1, label %BB2 +BB1: + %Div = fdiv double 1.0, 1.0 + %Val = fneg double %Div + br label %BB3 +BB2: + br label %BB3 +BB3: + %Ret = phi double [%Val, %BB1], [1.0, %BB2] + ret double %Ret +; CHECK-LABEL: @test1( +; CHECK: [[PHI:%.*]] = phi double [ -1.000000e+00, %BB1 ], [ 1.000000e+00, %BB2 ] +} diff --git a/llvm/test/Transforms/SCCP/undef-resolve.ll b/llvm/test/Transforms/SCCP/undef-resolve.ll index dd7f1f3..7fdcd55 100644 --- a/llvm/test/Transforms/SCCP/undef-resolve.ll +++ b/llvm/test/Transforms/SCCP/undef-resolve.ll @@ -180,3 +180,11 @@ entry: ; CHECK-LABEL: @test11( ; CHECK: ret i32 0 } + +; Test unary ops +define double @test12(double %x) { + %t = fneg double undef + ret double %t +; CHECK-LABEL: @test12( +; CHECK: double undef +} -- 2.7.4