Skip to content

Commit

Permalink
[SimplifyLibCalls] fdim constant fold (llvm#109235)
Browse files Browse the repository at this point in the history
2nd PR to fix llvm#108695 

based on llvm#108702

---------

Signed-off-by: Kushal Pal <kushalpal109@gmail.com>
  • Loading branch information
braw-lee authored Oct 10, 2024
1 parent bb34008 commit 3645c64
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 0 deletions.
1 change: 1 addition & 0 deletions llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ class LibCallSimplifier {
Value *optimizeTrigInversionPairs(CallInst *CI, IRBuilderBase &B);
Value *optimizeSymmetric(CallInst *CI, LibFunc Func, IRBuilderBase &B);
Value *optimizeRemquo(CallInst *CI, IRBuilderBase &B);
Value *optimizeFdim(CallInst *CI, IRBuilderBase &B);
// Wrapper for all floating point library call optimizations
Value *optimizeFloatingPointLibCall(CallInst *CI, LibFunc Func,
IRBuilderBase &B);
Expand Down
31 changes: 31 additions & 0 deletions llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3126,6 +3126,33 @@ Value *LibCallSimplifier::optimizeRemquo(CallInst *CI, IRBuilderBase &B) {
return ConstantFP::get(CI->getType(), Rem);
}

/// Constant folds fdim
Value *LibCallSimplifier::optimizeFdim(CallInst *CI, IRBuilderBase &B) {
// Cannot perform the fold unless the call has attribute memory(none)
if (!CI->doesNotAccessMemory())
return nullptr;

// TODO : Handle undef values
// Propagate poison if any
if (isa<PoisonValue>(CI->getArgOperand(0)))
return CI->getArgOperand(0);
if (isa<PoisonValue>(CI->getArgOperand(1)))
return CI->getArgOperand(1);

const APFloat *X, *Y;
// Check if both values are constants
if (!match(CI->getArgOperand(0), m_APFloat(X)) ||
!match(CI->getArgOperand(1), m_APFloat(Y)))
return nullptr;

APFloat Difference = *X;
Difference.subtract(*Y, RoundingMode::NearestTiesToEven);

APFloat MaxVal =
maximum(Difference, APFloat::getZero(CI->getType()->getFltSemantics()));
return ConstantFP::get(CI->getType(), MaxVal);
}

//===----------------------------------------------------------------------===//
// Integer Library Call Optimizations
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -4059,6 +4086,10 @@ Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI,
if (hasFloatVersion(M, CI->getCalledFunction()->getName()))
return optimizeBinaryDoubleFP(CI, Builder, TLI);
return nullptr;
case LibFunc_fdim:
case LibFunc_fdimf:
case LibFunc_fdiml:
return optimizeFdim(CI, Builder);
case LibFunc_fminf:
case LibFunc_fmin:
case LibFunc_fminl:
Expand Down
139 changes: 139 additions & 0 deletions llvm/test/Transforms/InstCombine/fdim.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=instcombine -S | FileCheck %s

define double @fdim_double() {
; CHECK-LABEL: define double @fdim_double() {
; CHECK-NEXT: ret double 2.500000e+00
;
%dim = call double @fdim(double 10.5, double 8.0)
ret double %dim
}

define double @fdim_double1() {
; CHECK-LABEL: define double @fdim_double1() {
; CHECK-NEXT: ret double 0.000000e+00
;
%dim = call double @fdim(double 7.0, double 8.0)
ret double %dim
}

define float @fdim_float() {
; CHECK-LABEL: define float @fdim_float() {
; CHECK-NEXT: ret float 0.000000e+00
;
%dim = call float @fdimf(float 1.500000e+00, float 8.0)
ret float %dim
}

define float @fdim_float1() {
; CHECK-LABEL: define float @fdim_float1() {
; CHECK-NEXT: ret float 2.000000e+00
;
%dim = call float @fdimf(float 1.000000e+01, float 8.0)
ret float %dim
}

define double @fdim_poison1() {
; CHECK-LABEL: define double @fdim_poison1() {
; CHECK-NEXT: ret double poison
;
%dim = call double @fdim(double poison, double 1.0)
ret double %dim
}

define double @fdim_poison2() {
; CHECK-LABEL: define double @fdim_poison2() {
; CHECK-NEXT: ret double poison
;
%dim = call double @fdim(double 1.0, double poison)
ret double %dim
}

define double @fdim_poison3() {
; CHECK-LABEL: define double @fdim_poison3() {
; CHECK-NEXT: ret double poison
;
%dim = call double @fdim(double poison, double poison)
ret double %dim
}

; undef folding is not implemented yet
define double @fdim_undef1() {
; CHECK-LABEL: define double @fdim_undef1() {
; CHECK-NEXT: [[DIM:%.*]] = call double @fdim(double undef, double 1.000000e+00)
; CHECK-NEXT: ret double [[DIM]]
;
%dim = call double @fdim(double undef, double 1.0)
ret double %dim
}

define double @fdim_inf_ninf() {
; CHECK-LABEL: define double @fdim_inf_ninf() {
; CHECK-NEXT: ret double 0x7FF0000000000000
;
%dim = call double @fdim(double 0x7FF0000000000000, double 0x8000000000000000 )
ret double %dim
}

define double @fdim_inf() {
; CHECK-LABEL: define double @fdim_inf() {
; CHECK-NEXT: ret double 0x7FF8000000000000
;
%dim = call double @fdim(double 0x7FF0000000000000, double 0x7FF0000000000000)
ret double %dim
}

define double @fdim_nzero() {
; CHECK-LABEL: define double @fdim_nzero() {
; CHECK-NEXT: ret double 0.000000e+00
;
%dim = call double @fdim(double -0.0, double +0.0)
ret double %dim
}

define double @fdim_strictfp() {
; CHECK-LABEL: define double @fdim_strictfp() {
; CHECK-NEXT: [[DIM:%.*]] = call double @fdim(double 1.000000e+01, double 8.000000e+00) #[[ATTR1:[0-9]+]]
; CHECK-NEXT: ret double [[DIM]]
;
%dim = call double @fdim(double 10.0, double 8.0) strictfp
ret double %dim
}

define double @fdim_nan1() {
; CHECK-LABEL: define double @fdim_nan1() {
; CHECK-NEXT: ret double 0x7FF8000000000000
;
%dim = call double @fdim(double 10.0, double 0x7FF8000000000000)
ret double %dim
}


define double @fdim_nan2() {
; CHECK-LABEL: define double @fdim_nan2() {
; CHECK-NEXT: ret double 0x7FF8000000000000
;
%dim = call double @fdim(double 0x7FF8000000000000, double 1.4)
ret double %dim
}

define double @fdim_snan1() {
; CHECK-LABEL: define double @fdim_snan1() {
; CHECK-NEXT: ret double 0x7FFC000000000000
;
%dim = call double @fdim(double 0x7FF4000000000000, double 1.4)
ret double %dim
}

define double @fdim_snan2() {
; CHECK-LABEL: define double @fdim_snan2() {
; CHECK-NEXT: ret double 0x7FFC000000000000
;
%dim = call double @fdim(double 1.7, double 0x7FF4000000000000)
ret double %dim
}

declare double @fdim(double, double) #0
declare float @fdimf(float, float) #0

attributes #0 = { memory(none) }
36 changes: 36 additions & 0 deletions llvm/test/Transforms/InstCombine/win-fdim.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt %s -passes=instcombine -S -mtriple=i386-pc-windows-msvc | FileCheck %s --check-prefixes=MSVC19

define double @fdim_double() {
; MSVC19-LABEL: define double @fdim_double() {
; MSVC19-NEXT: ret double 2.500000e+00
;
%dim = call double @fdim(double 10.5, double 8.0)
ret double %dim
}

;fdimf is not supported by windows
define float @fdim_float() {
; MSVC19-LABEL: define float @fdim_float() {
; MSVC19-NEXT: [[DIM:%.*]] = call float @fdimf(float 1.500000e+00, float 8.000000e+00)
; MSVC19-NEXT: ret float [[DIM]]
;
%dim = call float @fdimf(float 1.500000e+00, float 8.0)
ret float %dim
}

;fdiml is not supported by windows
define fp128 @fdim_long() {
; MSVC19-LABEL: define fp128 @fdim_long() {
; MSVC19-NEXT: [[DIM:%.*]] = call fp128 @fdiml(fp128 0xL00000000000000000000000000000000, fp128 0xL00000000000000000000000000000000)
; MSVC19-NEXT: ret fp128 [[DIM]]
;
%dim = call fp128 @fdiml(fp128 0xL00000000000000000000000000000000 , fp128 0xL00000000000000000000000000000000)
ret fp128 %dim
}

declare double @fdim(double, double) #0
declare float @fdimf(float, float) #0
declare fp128 @fdiml(fp128, fp128) #0

attributes #0 = { memory(none) }

0 comments on commit 3645c64

Please sign in to comment.