Skip to content

Commit 8d976c7

Browse files
committed
[InstCombine] Make (binop ({s|u}itofp),({s|u}itofp)) transform more flexible to mismatched signs
Instead of taking the sign of the cast operation as the required since for the transform, only force a sign if an operation is maybe negative. This gives us more flexability when checking if the floats are safely converable to integers. Closes llvm#84389
1 parent 938b920 commit 8d976c7

File tree

4 files changed

+78
-62
lines changed

4 files changed

+78
-62
lines changed

llvm/lib/Transforms/InstCombine/InstCombineInternal.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,10 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
380380
Instruction *foldBitcastExtElt(ExtractElementInst &ExtElt);
381381
Instruction *foldCastedBitwiseLogic(BinaryOperator &I);
382382
Instruction *foldFBinOpOfIntCasts(BinaryOperator &I);
383+
// Should only be called by `foldFBinOpOfIntCasts`.
384+
Instruction *foldFBinOpOfIntCastsFromSign(
385+
BinaryOperator &BO, bool OpsFromSigned, std::array<Value *, 2> IntOps,
386+
Constant *Op1FpC, SmallVectorImpl<WithCache<const Value *>> &OpsKnown);
383387
Instruction *foldBinopOfSextBoolToSelect(BinaryOperator &I);
384388
Instruction *narrowBinOp(TruncInst &Trunc);
385389
Instruction *narrowMaskedBinOp(BinaryOperator &And);

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 49 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,41 +1406,27 @@ Value *InstCombinerImpl::dyn_castNegVal(Value *V) const {
14061406
// -> ({s|u}itofp (int_binop x, y))
14071407
// 2) (fp_binop ({s|u}itofp x), FpC)
14081408
// -> ({s|u}itofp (int_binop x, (fpto{s|u}i FpC)))
1409-
Instruction *InstCombinerImpl::foldFBinOpOfIntCasts(BinaryOperator &BO) {
1410-
Value *IntOps[2] = {nullptr, nullptr};
1411-
Constant *Op1FpC = nullptr;
1412-
1413-
// Check for:
1414-
// 1) (binop ({s|u}itofp x), ({s|u}itofp y))
1415-
// 2) (binop ({s|u}itofp x), FpC)
1416-
if (!match(BO.getOperand(0), m_SIToFP(m_Value(IntOps[0]))) &&
1417-
!match(BO.getOperand(0), m_UIToFP(m_Value(IntOps[0]))))
1418-
return nullptr;
1419-
1420-
if (!match(BO.getOperand(1), m_Constant(Op1FpC)) &&
1421-
!match(BO.getOperand(1), m_SIToFP(m_Value(IntOps[1]))) &&
1422-
!match(BO.getOperand(1), m_UIToFP(m_Value(IntOps[1]))))
1423-
return nullptr;
1409+
//
1410+
// Assuming the sign of the cast for x/y is `OpsFromSigned`.
1411+
Instruction *InstCombinerImpl::foldFBinOpOfIntCastsFromSign(
1412+
BinaryOperator &BO, bool OpsFromSigned, std::array<Value *, 2> IntOps,
1413+
Constant *Op1FpC, SmallVectorImpl<WithCache<const Value *>> &OpsKnown) {
14241414

14251415
Type *FPTy = BO.getType();
14261416
Type *IntTy = IntOps[0]->getType();
14271417

1428-
// Do we have signed casts?
1429-
bool OpsFromSigned = isa<SIToFPInst>(BO.getOperand(0));
1430-
14311418
unsigned IntSz = IntTy->getScalarSizeInBits();
14321419
// This is the maximum number of inuse bits by the integer where the int -> fp
14331420
// casts are exact.
14341421
unsigned MaxRepresentableBits =
14351422
APFloat::semanticsPrecision(FPTy->getScalarType()->getFltSemantics());
14361423

1437-
// Cache KnownBits a bit to potentially save some analysis.
1438-
WithCache<const Value *> OpsKnown[2] = {IntOps[0], IntOps[1]};
1439-
14401424
// Preserve known number of leading bits. This can allow us to trivial nsw/nuw
14411425
// checks later on.
14421426
unsigned NumUsedLeadingBits[2] = {IntSz, IntSz};
14431427

1428+
// NB: This only comes up if OpsFromSigned is true, so there is no need to
1429+
// cache if between calls to `foldFBinOpOfIntCastsFromSign`.
14441430
auto IsNonZero = [&](unsigned OpNo) -> bool {
14451431
if (OpsKnown[OpNo].hasKnownBits() &&
14461432
OpsKnown[OpNo].getKnownBits(SQ).isNonZero())
@@ -1449,14 +1435,19 @@ Instruction *InstCombinerImpl::foldFBinOpOfIntCasts(BinaryOperator &BO) {
14491435
};
14501436

14511437
auto IsNonNeg = [&](unsigned OpNo) -> bool {
1452-
if (OpsKnown[OpNo].hasKnownBits() &&
1453-
OpsKnown[OpNo].getKnownBits(SQ).isNonNegative())
1454-
return true;
1455-
return isKnownNonNegative(IntOps[OpNo], SQ);
1438+
// NB: This matches the impl in ValueTracking, we just try to use cached
1439+
// knownbits here. If we ever start supporting WithCache for
1440+
// `isKnownNonNegative`, change this to an explicit call.
1441+
return OpsKnown[OpNo].getKnownBits(SQ).isNonNegative();
14561442
};
14571443

14581444
// Check if we know for certain that ({s|u}itofp op) is exact.
14591445
auto IsValidPromotion = [&](unsigned OpNo) -> bool {
1446+
// Can we treat this operand as the desired sign?
1447+
if (OpsFromSigned != isa<SIToFPInst>(BO.getOperand(OpNo)) &&
1448+
!IsNonNeg(OpNo))
1449+
return false;
1450+
14601451
// If fp precision >= bitwidth(op) then its exact.
14611452
// NB: This is slightly conservative for `sitofp`. For signed conversion, we
14621453
// can handle `MaxRepresentableBits == IntSz - 1` as the sign bit will be
@@ -1509,13 +1500,6 @@ Instruction *InstCombinerImpl::foldFBinOpOfIntCasts(BinaryOperator &BO) {
15091500
return nullptr;
15101501

15111502
if (Op1FpC == nullptr) {
1512-
if (OpsFromSigned != isa<SIToFPInst>(BO.getOperand(1))) {
1513-
// If we have a signed + unsigned, see if we can treat both as signed
1514-
// (uitofp nneg x) == (sitofp nneg x).
1515-
if (OpsFromSigned ? !IsNonNeg(1) : !IsNonNeg(0))
1516-
return nullptr;
1517-
OpsFromSigned = true;
1518-
}
15191503
if (!IsValidPromotion(1))
15201504
return nullptr;
15211505
}
@@ -1574,6 +1558,39 @@ Instruction *InstCombinerImpl::foldFBinOpOfIntCasts(BinaryOperator &BO) {
15741558
return new UIToFPInst(IntBinOp, FPTy);
15751559
}
15761560

1561+
// Try to fold:
1562+
// 1) (fp_binop ({s|u}itofp x), ({s|u}itofp y))
1563+
// -> ({s|u}itofp (int_binop x, y))
1564+
// 2) (fp_binop ({s|u}itofp x), FpC)
1565+
// -> ({s|u}itofp (int_binop x, (fpto{s|u}i FpC)))
1566+
Instruction *InstCombinerImpl::foldFBinOpOfIntCasts(BinaryOperator &BO) {
1567+
std::array<Value *, 2> IntOps = {nullptr, nullptr};
1568+
Constant *Op1FpC = nullptr;
1569+
// Check for:
1570+
// 1) (binop ({s|u}itofp x), ({s|u}itofp y))
1571+
// 2) (binop ({s|u}itofp x), FpC)
1572+
if (!match(BO.getOperand(0), m_SIToFP(m_Value(IntOps[0]))) &&
1573+
!match(BO.getOperand(0), m_UIToFP(m_Value(IntOps[0]))))
1574+
return nullptr;
1575+
1576+
if (!match(BO.getOperand(1), m_Constant(Op1FpC)) &&
1577+
!match(BO.getOperand(1), m_SIToFP(m_Value(IntOps[1]))) &&
1578+
!match(BO.getOperand(1), m_UIToFP(m_Value(IntOps[1]))))
1579+
return nullptr;
1580+
1581+
// Cache KnownBits a bit to potentially save some analysis.
1582+
SmallVector<WithCache<const Value *>, 2> OpsKnown = {IntOps[0], IntOps[1]};
1583+
1584+
// Try treating x/y as coming from both `uitofp` and `sitofp`. There are
1585+
// different constraints depending on the sign of the cast.
1586+
// NB: `(uitofp nneg X)` == `(sitofp nneg X)`.
1587+
if (Instruction *R = foldFBinOpOfIntCastsFromSign(BO, /*OpsFromSigned=*/false,
1588+
IntOps, Op1FpC, OpsKnown))
1589+
return R;
1590+
return foldFBinOpOfIntCastsFromSign(BO, /*OpsFromSigned=*/true, IntOps,
1591+
Op1FpC, OpsKnown);
1592+
}
1593+
15771594
/// A binop with a constant operand and a sign-extended boolean operand may be
15781595
/// converted into a select of constants by applying the binary operation to
15791596
/// the constant with the two possible values of the extended boolean (0 or -1).

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ define double @x(i32 %a, i32 %b) {
66
; CHECK-NEXT: [[M:%.*]] = lshr i32 [[A:%.*]], 24
77
; CHECK-NEXT: [[N:%.*]] = and i32 [[M]], [[B:%.*]]
88
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[N]], 1
9-
; CHECK-NEXT: [[P:%.*]] = sitofp i32 [[TMP1]] to double
9+
; CHECK-NEXT: [[P:%.*]] = uitofp i32 [[TMP1]] to double
1010
; CHECK-NEXT: ret double [[P]]
1111
;
1212
%m = lshr i32 %a, 24
@@ -20,7 +20,7 @@ define double @test(i32 %a) {
2020
; CHECK-LABEL: @test(
2121
; CHECK-NEXT: [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
2222
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[A_AND]], 1
23-
; CHECK-NEXT: [[RES:%.*]] = sitofp i32 [[TMP1]] to double
23+
; CHECK-NEXT: [[RES:%.*]] = uitofp i32 [[TMP1]] to double
2424
; CHECK-NEXT: ret double [[RES]]
2525
;
2626
; Drop two highest bits to guarantee that %a + 1 doesn't overflow
@@ -49,7 +49,7 @@ define double @test_2(i32 %a, i32 %b) {
4949
; CHECK-NEXT: [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
5050
; CHECK-NEXT: [[B_AND:%.*]] = and i32 [[B:%.*]], 1073741823
5151
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[A_AND]], [[B_AND]]
52-
; CHECK-NEXT: [[RES:%.*]] = sitofp i32 [[TMP1]] to double
52+
; CHECK-NEXT: [[RES:%.*]] = uitofp i32 [[TMP1]] to double
5353
; CHECK-NEXT: ret double [[RES]]
5454
;
5555
; Drop two highest bits to guarantee that %a + %b doesn't overflow
@@ -89,7 +89,7 @@ define float @test_3(i32 %a, i32 %b) {
8989
; CHECK-NEXT: [[M:%.*]] = lshr i32 [[A:%.*]], 24
9090
; CHECK-NEXT: [[N:%.*]] = and i32 [[M]], [[B:%.*]]
9191
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[N]], 1
92-
; CHECK-NEXT: [[P:%.*]] = sitofp i32 [[TMP1]] to float
92+
; CHECK-NEXT: [[P:%.*]] = uitofp i32 [[TMP1]] to float
9393
; CHECK-NEXT: ret float [[P]]
9494
;
9595
%m = lshr i32 %a, 24
@@ -104,7 +104,7 @@ define <4 x double> @test_4(<4 x i32> %a, <4 x i32> %b) {
104104
; CHECK-NEXT: [[A_AND:%.*]] = and <4 x i32> [[A:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
105105
; CHECK-NEXT: [[B_AND:%.*]] = and <4 x i32> [[B:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
106106
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw <4 x i32> [[A_AND]], [[B_AND]]
107-
; CHECK-NEXT: [[RES:%.*]] = sitofp <4 x i32> [[TMP1]] to <4 x double>
107+
; CHECK-NEXT: [[RES:%.*]] = uitofp <4 x i32> [[TMP1]] to <4 x double>
108108
; CHECK-NEXT: ret <4 x double> [[RES]]
109109
;
110110
; Drop two highest bits to guarantee that %a + %b doesn't overflow

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

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ define half @test_ui_si_i8_add(i8 noundef %x_in, i8 noundef %y_in) {
110110
; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 63
111111
; CHECK-NEXT: [[Y:%.*]] = and i8 [[Y_IN:%.*]], 63
112112
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i8 [[X]], [[Y]]
113-
; CHECK-NEXT: [[R:%.*]] = sitofp i8 [[TMP1]] to half
113+
; CHECK-NEXT: [[R:%.*]] = uitofp i8 [[TMP1]] to half
114114
; CHECK-NEXT: ret half [[R]]
115115
;
116116
%x = and i8 %x_in, 63
@@ -125,9 +125,8 @@ define half @test_ui_si_i8_add_overflow(i8 noundef %x_in, i8 noundef %y_in) {
125125
; CHECK-LABEL: @test_ui_si_i8_add_overflow(
126126
; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 63
127127
; CHECK-NEXT: [[Y:%.*]] = and i8 [[Y_IN:%.*]], 65
128-
; CHECK-NEXT: [[XF:%.*]] = sitofp i8 [[X]] to half
129-
; CHECK-NEXT: [[YF:%.*]] = uitofp i8 [[Y]] to half
130-
; CHECK-NEXT: [[R:%.*]] = fadd half [[XF]], [[YF]]
128+
; CHECK-NEXT: [[TMP1:%.*]] = add nuw i8 [[X]], [[Y]]
129+
; CHECK-NEXT: [[R:%.*]] = uitofp i8 [[TMP1]] to half
131130
; CHECK-NEXT: ret half [[R]]
132131
;
133132
%x = and i8 %x_in, 63
@@ -152,9 +151,8 @@ define half @test_ui_ui_i8_sub_C(i8 noundef %x_in) {
152151

153152
define half @test_ui_ui_i8_sub_C_fail_overflow(i8 noundef %x_in) {
154153
; CHECK-LABEL: @test_ui_ui_i8_sub_C_fail_overflow(
155-
; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 127
156-
; CHECK-NEXT: [[XF:%.*]] = uitofp i8 [[X]] to half
157-
; CHECK-NEXT: [[R:%.*]] = fadd half [[XF]], 0xHD800
154+
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[X_IN:%.*]], -128
155+
; CHECK-NEXT: [[R:%.*]] = sitofp i8 [[TMP1]] to half
158156
; CHECK-NEXT: ret half [[R]]
159157
;
160158
%x = and i8 %x_in, 127
@@ -212,8 +210,8 @@ define half @test_si_si_i8_sub_C(i8 noundef %x_in) {
212210
define half @test_si_si_i8_sub_C_fail_overflow(i8 noundef %x_in) {
213211
; CHECK-LABEL: @test_si_si_i8_sub_C_fail_overflow(
214212
; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 65
215-
; CHECK-NEXT: [[XF:%.*]] = sitofp i8 [[X]] to half
216-
; CHECK-NEXT: [[R:%.*]] = fadd half [[XF]], 0xH5400
213+
; CHECK-NEXT: [[TMP1:%.*]] = add nuw i8 [[X]], 64
214+
; CHECK-NEXT: [[R:%.*]] = uitofp i8 [[TMP1]] to half
217215
; CHECK-NEXT: ret half [[R]]
218216
;
219217
%x = and i8 %x_in, 65
@@ -242,9 +240,8 @@ define half @test_ui_si_i8_sub_fail_maybe_sign(i8 noundef %x_in, i8 noundef %y_i
242240
; CHECK-LABEL: @test_ui_si_i8_sub_fail_maybe_sign(
243241
; CHECK-NEXT: [[X:%.*]] = or i8 [[X_IN:%.*]], 64
244242
; CHECK-NEXT: [[Y:%.*]] = and i8 [[Y_IN:%.*]], 63
245-
; CHECK-NEXT: [[XF:%.*]] = uitofp i8 [[X]] to half
246-
; CHECK-NEXT: [[YF:%.*]] = sitofp i8 [[Y]] to half
247-
; CHECK-NEXT: [[R:%.*]] = fsub half [[XF]], [[YF]]
243+
; CHECK-NEXT: [[TMP1:%.*]] = sub nuw nsw i8 [[X]], [[Y]]
244+
; CHECK-NEXT: [[R:%.*]] = uitofp i8 [[TMP1]] to half
248245
; CHECK-NEXT: ret half [[R]]
249246
;
250247
%x = or i8 %x_in, 64
@@ -273,8 +270,8 @@ define half @test_ui_ui_i8_mul(i8 noundef %x_in, i8 noundef %y_in) {
273270

274271
define half @test_ui_ui_i8_mul_C(i8 noundef %x_in) {
275272
; CHECK-LABEL: @test_ui_ui_i8_mul_C(
276-
; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X_IN:%.*]], 4
277-
; CHECK-NEXT: [[R:%.*]] = uitofp i8 [[TMP1]] to half
273+
; CHECK-NEXT: [[X:%.*]] = shl i8 [[X_IN:%.*]], 4
274+
; CHECK-NEXT: [[R:%.*]] = uitofp i8 [[X]] to half
278275
; CHECK-NEXT: ret half [[R]]
279276
;
280277
%x = and i8 %x_in, 15
@@ -368,7 +365,7 @@ define half @test_ui_si_i8_mul(i8 noundef %x_in, i8 noundef %y_in) {
368365
; CHECK-NEXT: [[YY:%.*]] = and i8 [[Y_IN:%.*]], 7
369366
; CHECK-NEXT: [[Y:%.*]] = add nuw nsw i8 [[YY]], 1
370367
; CHECK-NEXT: [[TMP1:%.*]] = mul nuw nsw i8 [[X]], [[Y]]
371-
; CHECK-NEXT: [[R:%.*]] = sitofp i8 [[TMP1]] to half
368+
; CHECK-NEXT: [[R:%.*]] = uitofp i8 [[TMP1]] to half
372369
; CHECK-NEXT: ret half [[R]]
373370
;
374371
%xx = and i8 %x_in, 6
@@ -386,9 +383,8 @@ define half @test_ui_si_i8_mul_fail_maybe_zero(i8 noundef %x_in, i8 noundef %y_i
386383
; CHECK-NEXT: [[XX:%.*]] = and i8 [[X_IN:%.*]], 7
387384
; CHECK-NEXT: [[X:%.*]] = add nuw nsw i8 [[XX]], 1
388385
; CHECK-NEXT: [[Y:%.*]] = and i8 [[Y_IN:%.*]], 7
389-
; CHECK-NEXT: [[XF:%.*]] = sitofp i8 [[X]] to half
390-
; CHECK-NEXT: [[YF:%.*]] = uitofp i8 [[Y]] to half
391-
; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], [[YF]]
386+
; CHECK-NEXT: [[TMP1:%.*]] = mul nuw nsw i8 [[X]], [[Y]]
387+
; CHECK-NEXT: [[R:%.*]] = uitofp i8 [[TMP1]] to half
392388
; CHECK-NEXT: ret half [[R]]
393389
;
394390
%xx = and i8 %x_in, 7
@@ -694,7 +690,7 @@ define half @test_ui_si_i16_mul(i16 noundef %x_in, i16 noundef %y_in) {
694690
; CHECK-NEXT: [[YY:%.*]] = and i16 [[Y_IN:%.*]], 126
695691
; CHECK-NEXT: [[Y:%.*]] = or disjoint i16 [[YY]], 1
696692
; CHECK-NEXT: [[TMP1:%.*]] = mul nuw nsw i16 [[X]], [[Y]]
697-
; CHECK-NEXT: [[R:%.*]] = sitofp i16 [[TMP1]] to half
693+
; CHECK-NEXT: [[R:%.*]] = uitofp i16 [[TMP1]] to half
698694
; CHECK-NEXT: ret half [[R]]
699695
;
700696
%xx = and i16 %x_in, 126
@@ -807,9 +803,8 @@ define half @test_ui_ui_i12_sub_fail_overflow(i12 noundef %x_in, i12 noundef %y_
807803
; CHECK-LABEL: @test_ui_ui_i12_sub_fail_overflow(
808804
; CHECK-NEXT: [[X:%.*]] = and i12 [[X_IN:%.*]], 1023
809805
; CHECK-NEXT: [[Y:%.*]] = and i12 [[Y_IN:%.*]], 2047
810-
; CHECK-NEXT: [[XF:%.*]] = uitofp i12 [[X]] to half
811-
; CHECK-NEXT: [[YF:%.*]] = uitofp i12 [[Y]] to half
812-
; CHECK-NEXT: [[R:%.*]] = fsub half [[XF]], [[YF]]
806+
; CHECK-NEXT: [[TMP1:%.*]] = sub nsw i12 [[X]], [[Y]]
807+
; CHECK-NEXT: [[R:%.*]] = sitofp i12 [[TMP1]] to half
813808
; CHECK-NEXT: ret half [[R]]
814809
;
815810
%x = and i12 %x_in, 1023
@@ -984,7 +979,7 @@ define half @test_ui_si_i12_mul_nsw(i12 noundef %x_in, i12 noundef %y_in) {
984979
; CHECK-NEXT: [[YY:%.*]] = and i12 [[Y_IN:%.*]], 30
985980
; CHECK-NEXT: [[Y:%.*]] = or disjoint i12 [[YY]], 1
986981
; CHECK-NEXT: [[TMP1:%.*]] = mul nuw nsw i12 [[X]], [[Y]]
987-
; CHECK-NEXT: [[R:%.*]] = sitofp i12 [[TMP1]] to half
982+
; CHECK-NEXT: [[R:%.*]] = uitofp i12 [[TMP1]] to half
988983
; CHECK-NEXT: ret half [[R]]
989984
;
990985
%xx = and i12 %x_in, 31
@@ -1000,8 +995,8 @@ define half @test_ui_si_i12_mul_nsw(i12 noundef %x_in, i12 noundef %y_in) {
1000995
define float @test_ui_add_with_signed_constant(i32 %shr.i) {
1001996
; CHECK-LABEL: @test_ui_add_with_signed_constant(
1002997
; CHECK-NEXT: [[AND_I:%.*]] = and i32 [[SHR_I:%.*]], 32767
1003-
; CHECK-NEXT: [[SUB:%.*]] = uitofp i32 [[AND_I]] to float
1004-
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[SUB]], -1.638300e+04
998+
; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[AND_I]], -16383
999+
; CHECK-NEXT: [[ADD:%.*]] = sitofp i32 [[TMP1]] to float
10051000
; CHECK-NEXT: ret float [[ADD]]
10061001
;
10071002
%and.i = and i32 %shr.i, 32767

0 commit comments

Comments
 (0)