Skip to content

Commit f9783c5

Browse files
authored
[InstCombine] Fix frexp(frexp(x)) -> frexp(x) fold (#138837)
Fixes #138819 When frexp is applied twice, the second result should be zero.
1 parent dbcfc43 commit f9783c5

File tree

4 files changed

+31
-22
lines changed

4 files changed

+31
-22
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6377,15 +6377,6 @@ static Value *simplifyUnaryIntrinsic(Function *F, Value *Op0,
63776377
if (isSplatValue(Op0))
63786378
return Op0;
63796379
break;
6380-
case Intrinsic::frexp: {
6381-
// Frexp is idempotent with the added complication of the struct return.
6382-
if (match(Op0, m_ExtractValue<0>(m_Value(X)))) {
6383-
if (match(X, m_Intrinsic<Intrinsic::frexp>(m_Value())))
6384-
return X;
6385-
}
6386-
6387-
break;
6388-
}
63896380
default:
63906381
break;
63916382
}

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3811,6 +3811,21 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
38113811
}
38123812
break;
38133813
}
3814+
case Intrinsic::frexp: {
3815+
Value *X;
3816+
// The first result is idempotent with the added complication of the struct
3817+
// return, and the second result is zero because the value is already
3818+
// normalized.
3819+
if (match(II->getArgOperand(0), m_ExtractValue<0>(m_Value(X)))) {
3820+
if (match(X, m_Intrinsic<Intrinsic::frexp>(m_Value()))) {
3821+
X = Builder.CreateInsertValue(
3822+
X, Constant::getNullValue(II->getType()->getStructElementType(1)),
3823+
1);
3824+
return replaceInstUsesWith(*II, X);
3825+
}
3826+
}
3827+
break;
3828+
}
38143829
default: {
38153830
// Handle target specific intrinsics
38163831
std::optional<Instruction *> V = targetInstCombineIntrinsic(*II);

llvm/test/CodeGen/AMDGPU/frexp-constant-fold.ll

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ define { float, i32 } @frexp_frexp(float %x) {
1010
; CHECK-LABEL: frexp_frexp:
1111
; CHECK: ; %bb.0:
1212
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
13-
; CHECK-NEXT: v_frexp_mant_f32_e32 v2, v0
14-
; CHECK-NEXT: v_frexp_exp_i32_f32_e32 v1, v0
15-
; CHECK-NEXT: v_mov_b32_e32 v0, v2
13+
; CHECK-NEXT: v_frexp_mant_f32_e32 v1, v0
14+
; CHECK-NEXT: v_frexp_mant_f32_e32 v0, v1
15+
; CHECK-NEXT: v_frexp_exp_i32_f32_e32 v1, v1
1616
; CHECK-NEXT: s_setpc_b64 s[30:31]
1717
%frexp0 = call { float, i32 } @llvm.frexp.f32.i32(float %x)
1818
%frexp0.0 = extractvalue { float, i32 } %frexp0, 0
@@ -24,12 +24,12 @@ define { <2 x float>, <2 x i32> } @frexp_frexp_vector(<2 x float> %x) {
2424
; CHECK-LABEL: frexp_frexp_vector:
2525
; CHECK: ; %bb.0:
2626
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
27-
; CHECK-NEXT: v_frexp_mant_f32_e32 v4, v0
28-
; CHECK-NEXT: v_frexp_mant_f32_e32 v5, v1
29-
; CHECK-NEXT: v_frexp_exp_i32_f32_e32 v2, v0
30-
; CHECK-NEXT: v_frexp_exp_i32_f32_e32 v3, v1
31-
; CHECK-NEXT: v_mov_b32_e32 v0, v4
32-
; CHECK-NEXT: v_mov_b32_e32 v1, v5
27+
; CHECK-NEXT: v_frexp_mant_f32_e32 v3, v1
28+
; CHECK-NEXT: v_frexp_mant_f32_e32 v2, v0
29+
; CHECK-NEXT: v_frexp_mant_f32_e32 v0, v2
30+
; CHECK-NEXT: v_frexp_mant_f32_e32 v1, v3
31+
; CHECK-NEXT: v_frexp_exp_i32_f32_e32 v2, v2
32+
; CHECK-NEXT: v_frexp_exp_i32_f32_e32 v3, v3
3333
; CHECK-NEXT: s_setpc_b64 s[30:31]
3434
%frexp0 = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> %x)
3535
%frexp0.0 = extractvalue { <2 x float>, <2 x i32> } %frexp0, 0

llvm/test/Transforms/InstSimplify/frexp.ll renamed to llvm/test/Transforms/InstCombine/frexp.ll

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
2-
; RUN: opt -S -passes=instsimplify %s | FileCheck %s
2+
; RUN: opt -S -passes=instcombine %s | FileCheck %s
33

44
declare { float, i32 } @llvm.frexp.f32.i32(float)
55
declare { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float>)
@@ -12,7 +12,8 @@ define { float, i32 } @frexp_frexp(float %x) {
1212
; CHECK-LABEL: define { float, i32 } @frexp_frexp(
1313
; CHECK-SAME: float [[X:%.*]]) {
1414
; CHECK-NEXT: [[FREXP0:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]])
15-
; CHECK-NEXT: ret { float, i32 } [[FREXP0]]
15+
; CHECK-NEXT: [[FREXP1:%.*]] = insertvalue { float, i32 } [[FREXP0]], i32 0, 1
16+
; CHECK-NEXT: ret { float, i32 } [[FREXP1]]
1617
;
1718
%frexp0 = call { float, i32 } @llvm.frexp.f32.i32(float %x)
1819
%frexp0.0 = extractvalue { float, i32 } %frexp0, 0
@@ -24,7 +25,8 @@ define { <2 x float>, <2 x i32> } @frexp_frexp_vector(<2 x float> %x) {
2425
; CHECK-LABEL: define { <2 x float>, <2 x i32> } @frexp_frexp_vector(
2526
; CHECK-SAME: <2 x float> [[X:%.*]]) {
2627
; CHECK-NEXT: [[FREXP0:%.*]] = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> [[X]])
27-
; CHECK-NEXT: ret { <2 x float>, <2 x i32> } [[FREXP0]]
28+
; CHECK-NEXT: [[FREXP1:%.*]] = insertvalue { <2 x float>, <2 x i32> } [[FREXP0]], <2 x i32> zeroinitializer, 1
29+
; CHECK-NEXT: ret { <2 x float>, <2 x i32> } [[FREXP1]]
2830
;
2931
%frexp0 = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> %x)
3032
%frexp0.0 = extractvalue { <2 x float>, <2 x i32> } %frexp0, 0
@@ -47,7 +49,8 @@ define { <vscale x 2 x float>, <vscale x 2 x i32> } @frexp_frexp_scalable_vector
4749
; CHECK-LABEL: define { <vscale x 2 x float>, <vscale x 2 x i32> } @frexp_frexp_scalable_vector(
4850
; CHECK-SAME: <vscale x 2 x float> [[X:%.*]]) {
4951
; CHECK-NEXT: [[FREXP0:%.*]] = call { <vscale x 2 x float>, <vscale x 2 x i32> } @llvm.frexp.nxv2f32.nxv2i32(<vscale x 2 x float> [[X]])
50-
; CHECK-NEXT: ret { <vscale x 2 x float>, <vscale x 2 x i32> } [[FREXP0]]
52+
; CHECK-NEXT: [[FREXP1:%.*]] = insertvalue { <vscale x 2 x float>, <vscale x 2 x i32> } [[FREXP0]], <vscale x 2 x i32> zeroinitializer, 1
53+
; CHECK-NEXT: ret { <vscale x 2 x float>, <vscale x 2 x i32> } [[FREXP1]]
5154
;
5255
%frexp0 = call { <vscale x 2 x float>, <vscale x 2 x i32> } @llvm.frexp.nxv2f32.nxv2i32(<vscale x 2 x float> %x)
5356
%frexp0.0 = extractvalue { <vscale x 2 x float>, <vscale x 2 x i32> } %frexp0, 0

0 commit comments

Comments
 (0)