Skip to content

Commit 0f5849e

Browse files
committed
[InstCombine] Move folding (add (sitofp x), (sitofp y)) impl to InstructionCombiner; NFC
1 parent 862e742 commit 0f5849e

File tree

5 files changed

+84
-69
lines changed

5 files changed

+84
-69
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 3 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1867,64 +1867,10 @@ Instruction *InstCombinerImpl::visitFAdd(BinaryOperator &I) {
18671867

18681868
// Check for (fadd double (sitofp x), y), see if we can merge this into an
18691869
// integer add followed by a promotion.
1870-
Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
1871-
if (SIToFPInst *LHSConv = dyn_cast<SIToFPInst>(LHS)) {
1872-
Value *LHSIntVal = LHSConv->getOperand(0);
1873-
Type *FPType = LHSConv->getType();
1874-
1875-
// TODO: This check is overly conservative. In many cases known bits
1876-
// analysis can tell us that the result of the addition has less significant
1877-
// bits than the integer type can hold.
1878-
auto IsValidPromotion = [](Type *FTy, Type *ITy) {
1879-
Type *FScalarTy = FTy->getScalarType();
1880-
Type *IScalarTy = ITy->getScalarType();
1881-
1882-
// Do we have enough bits in the significand to represent the result of
1883-
// the integer addition?
1884-
unsigned MaxRepresentableBits =
1885-
APFloat::semanticsPrecision(FScalarTy->getFltSemantics());
1886-
return IScalarTy->getIntegerBitWidth() <= MaxRepresentableBits;
1887-
};
1888-
1889-
// (fadd double (sitofp x), fpcst) --> (sitofp (add int x, intcst))
1890-
// ... if the constant fits in the integer value. This is useful for things
1891-
// like (double)(x & 1234) + 4.0 -> (double)((X & 1234)+4) which no longer
1892-
// requires a constant pool load, and generally allows the add to be better
1893-
// instcombined.
1894-
if (ConstantFP *CFP = dyn_cast<ConstantFP>(RHS))
1895-
if (IsValidPromotion(FPType, LHSIntVal->getType())) {
1896-
Constant *CI = ConstantFoldCastOperand(Instruction::FPToSI, CFP,
1897-
LHSIntVal->getType(), DL);
1898-
if (LHSConv->hasOneUse() &&
1899-
ConstantFoldCastOperand(Instruction::SIToFP, CI, I.getType(), DL) ==
1900-
CFP &&
1901-
willNotOverflowSignedAdd(LHSIntVal, CI, I)) {
1902-
// Insert the new integer add.
1903-
Value *NewAdd = Builder.CreateNSWAdd(LHSIntVal, CI, "addconv");
1904-
return new SIToFPInst(NewAdd, I.getType());
1905-
}
1906-
}
1907-
1908-
// (fadd double (sitofp x), (sitofp y)) --> (sitofp (add int x, y))
1909-
if (SIToFPInst *RHSConv = dyn_cast<SIToFPInst>(RHS)) {
1910-
Value *RHSIntVal = RHSConv->getOperand(0);
1911-
// It's enough to check LHS types only because we require int types to
1912-
// be the same for this transform.
1913-
if (IsValidPromotion(FPType, LHSIntVal->getType())) {
1914-
// Only do this if x/y have the same type, if at least one of them has a
1915-
// single use (so we don't increase the number of int->fp conversions),
1916-
// and if the integer add will not overflow.
1917-
if (LHSIntVal->getType() == RHSIntVal->getType() &&
1918-
(LHSConv->hasOneUse() || RHSConv->hasOneUse()) &&
1919-
willNotOverflowSignedAdd(LHSIntVal, RHSIntVal, I)) {
1920-
// Insert the new integer add.
1921-
Value *NewAdd = Builder.CreateNSWAdd(LHSIntVal, RHSIntVal, "addconv");
1922-
return new SIToFPInst(NewAdd, I.getType());
1923-
}
1924-
}
1925-
}
1926-
}
1870+
if (Instruction *R = foldFBinOpOfIntCasts(I))
1871+
return R;
19271872

1873+
Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
19281874
// Handle specials cases for FAdd with selects feeding the operation
19291875
if (Value *V = SimplifySelectsFeedingBinaryOp(I, LHS, RHS))
19301876
return replaceInstUsesWith(I, V);

llvm/lib/Transforms/InstCombine/InstCombineInternal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
379379
Instruction *scalarizePHI(ExtractElementInst &EI, PHINode *PN);
380380
Instruction *foldBitcastExtElt(ExtractElementInst &ExtElt);
381381
Instruction *foldCastedBitwiseLogic(BinaryOperator &I);
382+
Instruction *foldFBinOpOfIntCasts(BinaryOperator &I);
382383
Instruction *foldBinopOfSextBoolToSelect(BinaryOperator &I);
383384
Instruction *narrowBinOp(TruncInst &Trunc);
384385
Instruction *narrowMaskedBinOp(BinaryOperator &And);

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,6 +1401,74 @@ Value *InstCombinerImpl::dyn_castNegVal(Value *V) const {
14011401
return nullptr;
14021402
}
14031403

1404+
// Try to fold:
1405+
// 1) (add (sitofp x), (sitofp y))
1406+
// -> (sitofp (add x, y))
1407+
// 2) (add (sitofp x), FpC)
1408+
// -> (sitofp (add x, (fptosi FpC)))
1409+
Instruction *InstCombinerImpl::foldFBinOpOfIntCasts(BinaryOperator &BO) {
1410+
// Check for (fadd double (sitofp x), y), see if we can merge this into an
1411+
// integer add followed by a promotion.
1412+
Value *LHS = BO.getOperand(0), *RHS = BO.getOperand(1);
1413+
if (SIToFPInst *LHSConv = dyn_cast<SIToFPInst>(LHS)) {
1414+
Value *LHSIntVal = LHSConv->getOperand(0);
1415+
Type *FPType = LHSConv->getType();
1416+
1417+
// TODO: This check is overly conservative. In many cases known bits
1418+
// analysis can tell us that the result of the addition has less significant
1419+
// bits than the integer type can hold.
1420+
auto IsValidPromotion = [](Type *FTy, Type *ITy) {
1421+
Type *FScalarTy = FTy->getScalarType();
1422+
Type *IScalarTy = ITy->getScalarType();
1423+
1424+
// Do we have enough bits in the significand to represent the result of
1425+
// the integer addition?
1426+
unsigned MaxRepresentableBits =
1427+
APFloat::semanticsPrecision(FScalarTy->getFltSemantics());
1428+
return IScalarTy->getIntegerBitWidth() <= MaxRepresentableBits;
1429+
};
1430+
1431+
// (fadd double (sitofp x), fpcst) --> (sitofp (add int x, intcst))
1432+
// ... if the constant fits in the integer value. This is useful for things
1433+
// like (double)(x & 1234) + 4.0 -> (double)((X & 1234)+4) which no longer
1434+
// requires a constant pool load, and generally allows the add to be better
1435+
// instcombined.
1436+
if (ConstantFP *CFP = dyn_cast<ConstantFP>(RHS))
1437+
if (IsValidPromotion(FPType, LHSIntVal->getType())) {
1438+
Constant *CI = ConstantFoldCastOperand(Instruction::FPToSI, CFP,
1439+
LHSIntVal->getType(), DL);
1440+
if (LHSConv->hasOneUse() &&
1441+
ConstantFoldCastOperand(Instruction::SIToFP, CI, BO.getType(),
1442+
DL) == CFP &&
1443+
willNotOverflowSignedAdd(LHSIntVal, CI, BO)) {
1444+
// Insert the new integer add.
1445+
Value *NewAdd = Builder.CreateNSWAdd(LHSIntVal, CI);
1446+
return new SIToFPInst(NewAdd, BO.getType());
1447+
}
1448+
}
1449+
1450+
// (fadd double (sitofp x), (sitofp y)) --> (sitofp (add int x, y))
1451+
if (SIToFPInst *RHSConv = dyn_cast<SIToFPInst>(RHS)) {
1452+
Value *RHSIntVal = RHSConv->getOperand(0);
1453+
// It's enough to check LHS types only because we require int types to
1454+
// be the same for this transform.
1455+
if (IsValidPromotion(FPType, LHSIntVal->getType())) {
1456+
// Only do this if x/y have the same type, if at least one of them has a
1457+
// single use (so we don't increase the number of int->fp conversions),
1458+
// and if the integer add will not overflow.
1459+
if (LHSIntVal->getType() == RHSIntVal->getType() &&
1460+
(LHSConv->hasOneUse() || RHSConv->hasOneUse()) &&
1461+
willNotOverflowSignedAdd(LHSIntVal, RHSIntVal, BO)) {
1462+
// Insert the new integer add.
1463+
Value *NewAdd = Builder.CreateNSWAdd(LHSIntVal, RHSIntVal);
1464+
return new SIToFPInst(NewAdd, BO.getType());
1465+
}
1466+
}
1467+
}
1468+
}
1469+
return nullptr;
1470+
}
1471+
14041472
/// A binop with a constant operand and a sign-extended boolean operand may be
14051473
/// converted into a select of constants by applying the binary operation to
14061474
/// the constant with the two possible values of the extended boolean (0 or -1).

llvm/test/Transforms/InstCombine/add-sitofp.ll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ define double @x(i32 %a, i32 %b) {
55
; CHECK-LABEL: @x(
66
; CHECK-NEXT: [[M:%.*]] = lshr i32 [[A:%.*]], 24
77
; CHECK-NEXT: [[N:%.*]] = and i32 [[M]], [[B:%.*]]
8-
; CHECK-NEXT: [[ADDCONV:%.*]] = add nuw nsw i32 [[N]], 1
9-
; CHECK-NEXT: [[P:%.*]] = sitofp i32 [[ADDCONV]] to double
8+
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[N]], 1
9+
; CHECK-NEXT: [[P:%.*]] = sitofp i32 [[TMP1]] to double
1010
; CHECK-NEXT: ret double [[P]]
1111
;
1212
%m = lshr i32 %a, 24
@@ -19,8 +19,8 @@ define double @x(i32 %a, i32 %b) {
1919
define double @test(i32 %a) {
2020
; CHECK-LABEL: @test(
2121
; CHECK-NEXT: [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
22-
; CHECK-NEXT: [[ADDCONV:%.*]] = add nuw nsw i32 [[A_AND]], 1
23-
; CHECK-NEXT: [[RES:%.*]] = sitofp i32 [[ADDCONV]] to double
22+
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[A_AND]], 1
23+
; CHECK-NEXT: [[RES:%.*]] = sitofp i32 [[TMP1]] to double
2424
; CHECK-NEXT: ret double [[RES]]
2525
;
2626
; Drop two highest bits to guarantee that %a + 1 doesn't overflow
@@ -48,8 +48,8 @@ define double @test_2(i32 %a, i32 %b) {
4848
; CHECK-LABEL: @test_2(
4949
; CHECK-NEXT: [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
5050
; CHECK-NEXT: [[B_AND:%.*]] = and i32 [[B:%.*]], 1073741823
51-
; CHECK-NEXT: [[ADDCONV:%.*]] = add nuw nsw i32 [[A_AND]], [[B_AND]]
52-
; CHECK-NEXT: [[RES:%.*]] = sitofp i32 [[ADDCONV]] to double
51+
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[A_AND]], [[B_AND]]
52+
; CHECK-NEXT: [[RES:%.*]] = sitofp i32 [[TMP1]] to double
5353
; CHECK-NEXT: ret double [[RES]]
5454
;
5555
; Drop two highest bits to guarantee that %a + %b doesn't overflow
@@ -105,8 +105,8 @@ define <4 x double> @test_4(<4 x i32> %a, <4 x i32> %b) {
105105
; CHECK-LABEL: @test_4(
106106
; CHECK-NEXT: [[A_AND:%.*]] = and <4 x i32> [[A:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
107107
; CHECK-NEXT: [[B_AND:%.*]] = and <4 x i32> [[B:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
108-
; CHECK-NEXT: [[ADDCONV:%.*]] = add nuw nsw <4 x i32> [[A_AND]], [[B_AND]]
109-
; CHECK-NEXT: [[RES:%.*]] = sitofp <4 x i32> [[ADDCONV]] to <4 x double>
108+
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw <4 x i32> [[A_AND]], [[B_AND]]
109+
; CHECK-NEXT: [[RES:%.*]] = sitofp <4 x i32> [[TMP1]] to <4 x double>
110110
; CHECK-NEXT: ret <4 x double> [[RES]]
111111
;
112112
; Drop two highest bits to guarantee that %a + %b doesn't overflow

llvm/test/Transforms/InstCombine/binop-itofp.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ define half @test_si_si_i8_add(i8 noundef %x_in, i8 noundef %y_in) {
7878
; CHECK-LABEL: @test_si_si_i8_add(
7979
; CHECK-NEXT: [[X:%.*]] = or i8 [[X_IN:%.*]], -64
8080
; CHECK-NEXT: [[Y:%.*]] = or i8 [[Y_IN:%.*]], -64
81-
; CHECK-NEXT: [[ADDCONV:%.*]] = add nsw i8 [[X]], [[Y]]
82-
; CHECK-NEXT: [[R:%.*]] = sitofp i8 [[ADDCONV]] to half
81+
; CHECK-NEXT: [[TMP1:%.*]] = add nsw i8 [[X]], [[Y]]
82+
; CHECK-NEXT: [[R:%.*]] = sitofp i8 [[TMP1]] to half
8383
; CHECK-NEXT: ret half [[R]]
8484
;
8585
%x = or i8 %x_in, -64
@@ -204,8 +204,8 @@ define half @test_si_si_i8_sub_fail_overflow(i8 noundef %x_in, i8 noundef %y_in)
204204
define half @test_si_si_i8_sub_C(i8 noundef %x_in) {
205205
; CHECK-LABEL: @test_si_si_i8_sub_C(
206206
; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 63
207-
; CHECK-NEXT: [[ADDCONV:%.*]] = or disjoint i8 [[X]], 64
208-
; CHECK-NEXT: [[R:%.*]] = sitofp i8 [[ADDCONV]] to half
207+
; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[X]], 64
208+
; CHECK-NEXT: [[R:%.*]] = sitofp i8 [[TMP1]] to half
209209
; CHECK-NEXT: ret half [[R]]
210210
;
211211
%x = and i8 %x_in, 63

0 commit comments

Comments
 (0)