Skip to content

Commit c055999

Browse files
authored
[InstCombine] Fix FMF propagation in copysign Mag, (copysign ?, X) -> copysign Mag, X (#121574)
Closes #121432.
1 parent b51a082 commit c055999

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2673,8 +2673,12 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
26732673
// Propagate sign argument through nested calls:
26742674
// copysign Mag, (copysign ?, X) --> copysign Mag, X
26752675
Value *X;
2676-
if (match(Sign, m_Intrinsic<Intrinsic::copysign>(m_Value(), m_Value(X))))
2677-
return replaceOperand(*II, 1, X);
2676+
if (match(Sign, m_Intrinsic<Intrinsic::copysign>(m_Value(), m_Value(X)))) {
2677+
Value *CopySign = Builder.CreateCopySign(
2678+
Mag, X,
2679+
II->getFastMathFlags() & cast<Instruction>(Sign)->getFastMathFlags());
2680+
return replaceInstUsesWith(*II, CopySign);
2681+
}
26782682

26792683
// Clear sign-bit of constant magnitude:
26802684
// copysign -MagC, X --> copysign MagC, X

llvm/test/Transforms/InstCombine/copysign.ll

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,34 @@ define float @not_known_positive_sign_arg(float %x, float %y) {
8282

8383
define float @copysign_sign_arg(float %x, float %y, float %z) {
8484
; CHECK-LABEL: @copysign_sign_arg(
85-
; CHECK-NEXT: [[R:%.*]] = call ninf float @llvm.copysign.f32(float [[X:%.*]], float [[Z:%.*]])
85+
; CHECK-NEXT: [[R:%.*]] = call float @llvm.copysign.f32(float [[X:%.*]], float [[Z:%.*]])
8686
; CHECK-NEXT: ret float [[R]]
8787
;
8888
%s = call reassoc float @llvm.copysign.f32(float %y, float %z)
8989
%r = call ninf float @llvm.copysign.f32(float %x, float %s)
9090
ret float %r
9191
}
9292

93+
define float @copysign_sign_arg_nnan(float %x, float %y, float %z) {
94+
; CHECK-LABEL: @copysign_sign_arg_nnan(
95+
; CHECK-NEXT: [[R:%.*]] = call nnan float @llvm.copysign.f32(float [[X:%.*]], float [[Z:%.*]])
96+
; CHECK-NEXT: ret float [[R]]
97+
;
98+
%s = call nnan float @llvm.copysign.f32(float %y, float %z)
99+
%r = call nnan float @llvm.copysign.f32(float %x, float %s)
100+
ret float %r
101+
}
102+
103+
define float @copysign_sign_arg_mixed(float %x, float %y, float %z) {
104+
; CHECK-LABEL: @copysign_sign_arg_mixed(
105+
; CHECK-NEXT: [[R:%.*]] = call nsz float @llvm.copysign.f32(float [[X:%.*]], float [[Z:%.*]])
106+
; CHECK-NEXT: ret float [[R]]
107+
;
108+
%s = call ninf nsz float @llvm.copysign.f32(float %y, float %z)
109+
%r = call nnan nsz float @llvm.copysign.f32(float %x, float %s)
110+
ret float %r
111+
}
112+
93113
define float @fneg_mag(float %x, float %y) {
94114
; CHECK-LABEL: @fneg_mag(
95115
; CHECK-NEXT: [[R:%.*]] = call float @llvm.copysign.f32(float [[X:%.*]], float [[Y:%.*]])

0 commit comments

Comments
 (0)