Skip to content

Commit 366efcb

Browse files
Simplify cabs libcall if real or imaginary part is zero
1 parent d4e46f0 commit 366efcb

File tree

2 files changed

+83
-7
lines changed

2 files changed

+83
-7
lines changed

llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "llvm/IR/Intrinsics.h"
2828
#include "llvm/IR/Module.h"
2929
#include "llvm/IR/PatternMatch.h"
30+
#include "llvm/Support/Casting.h"
3031
#include "llvm/Support/CommandLine.h"
3132
#include "llvm/Support/KnownBits.h"
3233
#include "llvm/Support/MathExtras.h"
@@ -1958,25 +1959,46 @@ static Value *optimizeBinaryDoubleFP(CallInst *CI, IRBuilderBase &B,
19581959

19591960
// cabs(z) -> sqrt((creal(z)*creal(z)) + (cimag(z)*cimag(z)))
19601961
Value *LibCallSimplifier::optimizeCAbs(CallInst *CI, IRBuilderBase &B) {
1961-
if (!CI->isFast())
1962-
return nullptr;
1963-
1964-
// Propagate fast-math flags from the existing call to new instructions.
1965-
IRBuilderBase::FastMathFlagGuard Guard(B);
1966-
B.setFastMathFlags(CI->getFastMathFlags());
1967-
19681962
Value *Real, *Imag;
1963+
19691964
if (CI->arg_size() == 1) {
19701965
Value *Op = CI->getArgOperand(0);
19711966
assert(Op->getType()->isArrayTy() && "Unexpected signature for cabs!");
19721967
Real = B.CreateExtractValue(Op, 0, "real");
19731968
Imag = B.CreateExtractValue(Op, 1, "imag");
1969+
19741970
} else {
19751971
assert(CI->arg_size() == 2 && "Unexpected signature for cabs!");
19761972
Real = CI->getArgOperand(0);
19771973
Imag = CI->getArgOperand(1);
19781974
}
19791975

1976+
// if real or imaginary part is zero, simplify to abs(cimag(z))
1977+
// or abs(creal(z))
1978+
if (ConstantFP *ConstReal = dyn_cast<ConstantFP>(Real)) {
1979+
if (ConstReal->isZeroValue()) {
1980+
IRBuilderBase::FastMathFlagGuard Guard(B);
1981+
B.setFastMathFlags(CI->getFastMathFlags());
1982+
1983+
return copyFlags(
1984+
*CI, B.CreateUnaryIntrinsic(Intrinsic::fabs, Imag, nullptr, "cabs"));
1985+
}
1986+
} else if (ConstantFP *ConstReal = dyn_cast<ConstantFP>(Imag)) {
1987+
if (ConstReal->isZeroValue()) {
1988+
IRBuilderBase::FastMathFlagGuard Guard(B);
1989+
B.setFastMathFlags(CI->getFastMathFlags());
1990+
return copyFlags(
1991+
*CI, B.CreateUnaryIntrinsic(Intrinsic::fabs, Real, nullptr, "cabs"));
1992+
}
1993+
}
1994+
1995+
if (!CI->isFast())
1996+
return nullptr;
1997+
1998+
// Propagate fast-math flags from the existing call to new instructions.
1999+
IRBuilderBase::FastMathFlagGuard Guard(B);
2000+
B.setFastMathFlags(CI->getFastMathFlags());
2001+
19802002
Value *RealReal = B.CreateFMul(Real, Real);
19812003
Value *ImagImag = B.CreateFMul(Imag, Imag);
19822004

llvm/test/Transforms/InstCombine/cabs-discrete.ll

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,24 @@ define double @fast_cabs(double %real, double %imag) {
4040
ret double %call
4141
}
4242

43+
define double @fast_cabs_zero_real(double %imag) {
44+
; CHECK-LABEL: @fast_cabs_zero_real(
45+
; CHECK-NEXT: [[CABS:%.*]] = tail call double @llvm.fabs.f64(double [[IMAG:%.*]])
46+
; CHECK-NEXT: ret double [[CABS]]
47+
;
48+
%call = tail call double @cabs(double 0.0, double %imag)
49+
ret double %call
50+
}
51+
52+
define double @fast_cabs_zero_real(double %real) {
53+
; CHECK-LABEL: @fast_cabs_zero_real(
54+
; CHECK-NEXT: [[CABS:%.*]] = tail call double @llvm.fabs.f64(double [[REAL:%.*]])
55+
; CHECK-NEXT: ret double [[CABS]]
56+
;
57+
%call = tail call double @cabs(double %real, 0.0)
58+
ret double %call
59+
}
60+
4361
define float @fast_cabsf(float %real, float %imag) {
4462
; CHECK-LABEL: @fast_cabsf(
4563
; CHECK-NEXT: [[TMP1:%.*]] = fmul fast float [[REAL:%.*]], [[REAL]]
@@ -52,6 +70,24 @@ define float @fast_cabsf(float %real, float %imag) {
5270
ret float %call
5371
}
5472

73+
define float @fast_cabsf_zero_real(float %imag) {
74+
; CHECK-LABEL: @fast_cabsf_zero_real(
75+
; CHECK-NEXT: [[CABS:%.*]] = tail call float @llvm.fabs.f32(float [[IMAG:%.*]])
76+
; CHECK-NEXT: ret float [[CABS]]
77+
;
78+
%call = tail call float @cabsf(float 0.0, float %imag)
79+
ret float %call
80+
}
81+
82+
define float @fast_cabsf_zero_real(float %real) {
83+
; CHECK-LABEL: @fast_cabsf_zero_real(
84+
; CHECK-NEXT: [[CABS:%.*]] = tail call float @llvm.fabs.f64(float [[REAL:%.*]])
85+
; CHECK-NEXT: ret float [[CABS]]
86+
;
87+
%call = tail call float @cabsf(float %real, 0.0)
88+
ret float %call
89+
}
90+
5591
define fp128 @fast_cabsl(fp128 %real, fp128 %imag) {
5692
; CHECK-LABEL: @fast_cabsl(
5793
; CHECK-NEXT: [[TMP1:%.*]] = fmul fast fp128 [[REAL:%.*]], [[REAL]]
@@ -64,6 +100,24 @@ define fp128 @fast_cabsl(fp128 %real, fp128 %imag) {
64100
ret fp128 %call
65101
}
66102

103+
define fp128 @fast_cabsl_zero_real(fp128 %imag) {
104+
; CHECK-LABEL: @fast_cabsl_zero_real(
105+
; CHECK-NEXT: [[CABS:%.*]] = tail call fp128 @llvm.fabsl.f128(fp128 [[IMAG:%.*]])
106+
; CHECK-NEXT: ret fp128 [[CABS]]
107+
;
108+
%call = tail call fp128 @cabsl(double 0.0, fp128 %imag)
109+
ret fp128 %call
110+
}
111+
112+
define fp128 @fast_cabsl_zero_real(fp128 %real) {
113+
; CHECK-LABEL: @fast_cabsl_zero_real(
114+
; CHECK-NEXT: [[CABS:%.*]] = tail call fp128 @llvm.fabs.f128(fp128 [[REAL:%.*]])
115+
; CHECK-NEXT: ret fp128 [[CABS]]
116+
;
117+
%call = tail call fp128 @cabsl(fp128 %real, 0.0)
118+
ret fp128 %call
119+
}
120+
67121
declare double @cabs(double %real, double %imag)
68122
declare float @cabsf(float %real, float %imag)
69123
declare fp128 @cabsl(fp128 %real, fp128 %imag)

0 commit comments

Comments
 (0)