Skip to content

Commit 092de9b

Browse files
[InstCombine] Enable FAdd simplifications when user can ignore sign bit (#157757)
When FAdd result is used by fabs, we can safely ignore the sign bit of fp zero. This patch enables an instruction simplification optimization that folds fadd x, 0 ==> x, which would otherwise not work as the compiler cannot prove that the zero isn't -0. But if the result of the fadd is used by fabs we can simply ignore this and still do the optimization. Fixes #154238
1 parent 30010f4 commit 092de9b

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2002,6 +2002,16 @@ Instruction *InstCombinerImpl::visitFAdd(BinaryOperator &I) {
20022002
if (Instruction *FoldedFAdd = foldBinOpIntoSelectOrPhi(I))
20032003
return FoldedFAdd;
20042004

2005+
// B = fadd A, 0.0
2006+
// Z = Op B
2007+
// can be transformed into
2008+
// Z = Op A
2009+
// Where Op is such that we can ignore sign of 0 in fadd
2010+
Value *A;
2011+
if (match(&I, m_OneUse(m_FAdd(m_Value(A), m_AnyZeroFP()))) &&
2012+
canIgnoreSignBitOfZero(*I.use_begin()))
2013+
return replaceInstUsesWith(I, A);
2014+
20052015
// (-X) + Y --> Y - X
20062016
Value *X, *Y;
20072017
if (match(&I, m_c_FAdd(m_FNeg(m_Value(X)), m_Value(Y))))
@@ -3145,6 +3155,16 @@ Instruction *InstCombinerImpl::visitFSub(BinaryOperator &I) {
31453155
Value *X, *Y;
31463156
Constant *C;
31473157

3158+
// B = fsub A, 0.0
3159+
// Z = Op B
3160+
// can be transformed into
3161+
// Z = Op A
3162+
// Where Op is such that we can ignore sign of 0 in fsub
3163+
Value *A;
3164+
if (match(&I, m_OneUse(m_FSub(m_Value(A), m_AnyZeroFP()))) &&
3165+
canIgnoreSignBitOfZero(*I.use_begin()))
3166+
return replaceInstUsesWith(I, A);
3167+
31483168
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
31493169
// If Op0 is not -0.0 or we can ignore -0.0: Z - (X - Y) --> Z + (Y - X)
31503170
// Canonicalize to fadd to make analysis easier.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3+
define float @src(float %arg1) {
4+
; CHECK-LABEL: define float @src(
5+
; CHECK-SAME: float [[ARG1:%.*]]) {
6+
; CHECK-NEXT: [[V3:%.*]] = call float @llvm.fabs.f32(float [[ARG1]])
7+
; CHECK-NEXT: ret float [[V3]]
8+
;
9+
%v2 = fadd float %arg1, 0.000000e+00
10+
%v3 = call float @llvm.fabs.f32(float %v2)
11+
ret float %v3
12+
}
13+
14+
define float @src2(float %arg1) {
15+
; CHECK-LABEL: define float @src2(
16+
; CHECK-SAME: float [[ARG1:%.*]]) {
17+
; CHECK-NEXT: [[V2:%.*]] = fadd float [[ARG1]], 0.000000e+00
18+
; CHECK-NEXT: [[V3:%.*]] = call float @llvm.fabs.f32(float [[V2]])
19+
; CHECK-NEXT: [[V4:%.*]] = fsub float [[V2]], [[V3]]
20+
; CHECK-NEXT: ret float [[V4]]
21+
;
22+
%v2 = fadd float %arg1, 0.000000e+00
23+
%v3 = call float @llvm.fabs.f32(float %v2)
24+
%v4 = fsub float %v2, %v3
25+
ret float %v4
26+
}
27+
28+
define float @src_sub(float %arg1) {
29+
; CHECK-LABEL: define float @src_sub(
30+
; CHECK-SAME: float [[ARG1:%.*]]) {
31+
; CHECK-NEXT: [[V3:%.*]] = call float @llvm.fabs.f32(float [[ARG1]])
32+
; CHECK-NEXT: ret float [[V3]]
33+
;
34+
%v2 = fsub float %arg1, 0.000000e+00
35+
%v3 = call float @llvm.fabs.f32(float %v2)
36+
ret float %v3
37+
}

0 commit comments

Comments
 (0)