Skip to content

Commit

Permalink
[ExpandLargeFpConvert] Scalarize vector types. (#86954)
Browse files Browse the repository at this point in the history
expand-large-fp-convert cannot handle vector types.
If overly large vector element types survive into
isel, they will likely be scalarized there, but since
isel cannot handle scalar integer types of that size,
it will assert.

Handle vector types in expand-large-fp-convert by
scalarizing them and then expanding the scalar type
operation. For large vectors, this results in a
*massive* code expansion, but it's better than
asserting.
  • Loading branch information
bevin-hansson committed Apr 3, 2024
1 parent 4ef22fc commit 7edddee
Show file tree
Hide file tree
Showing 5 changed files with 521 additions and 8 deletions.
49 changes: 41 additions & 8 deletions llvm/lib/CodeGen/ExpandLargeFpConvert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,8 +568,29 @@ static void expandIToFP(Instruction *IToFP) {
IToFP->eraseFromParent();
}

static void scalarize(Instruction *I, SmallVectorImpl<Instruction *> &Replace) {
VectorType *VTy = cast<FixedVectorType>(I->getType());

IRBuilder<> Builder(I);

unsigned NumElements = VTy->getElementCount().getFixedValue();
Value *Result = PoisonValue::get(VTy);
for (unsigned Idx = 0; Idx < NumElements; ++Idx) {
Value *Ext = Builder.CreateExtractElement(I->getOperand(0), Idx);
Value *Cast = Builder.CreateCast(cast<CastInst>(I)->getOpcode(), Ext,
I->getType()->getScalarType());
Result = Builder.CreateInsertElement(Result, Cast, Idx);
if (isa<Instruction>(Cast))
Replace.push_back(cast<Instruction>(Cast));
}
I->replaceAllUsesWith(Result);
I->dropAllReferences();
I->eraseFromParent();
}

static bool runImpl(Function &F, const TargetLowering &TLI) {
SmallVector<Instruction *, 4> Replace;
SmallVector<Instruction *, 4> ReplaceVector;
bool Modified = false;

unsigned MaxLegalFpConvertBitWidth =
Expand All @@ -584,29 +605,36 @@ static bool runImpl(Function &F, const TargetLowering &TLI) {
switch (I.getOpcode()) {
case Instruction::FPToUI:
case Instruction::FPToSI: {
// TODO: This pass doesn't handle vectors.
if (I.getOperand(0)->getType()->isVectorTy())
// TODO: This pass doesn't handle scalable vectors.
if (I.getOperand(0)->getType()->isScalableTy())
continue;

auto *IntTy = dyn_cast<IntegerType>(I.getType());
auto *IntTy = dyn_cast<IntegerType>(I.getType()->getScalarType());
if (IntTy->getIntegerBitWidth() <= MaxLegalFpConvertBitWidth)
continue;

Replace.push_back(&I);
if (I.getOperand(0)->getType()->isVectorTy())
ReplaceVector.push_back(&I);
else
Replace.push_back(&I);
Modified = true;
break;
}
case Instruction::UIToFP:
case Instruction::SIToFP: {
// TODO: This pass doesn't handle vectors.
if (I.getOperand(0)->getType()->isVectorTy())
// TODO: This pass doesn't handle scalable vectors.
if (I.getOperand(0)->getType()->isScalableTy())
continue;

auto *IntTy = dyn_cast<IntegerType>(I.getOperand(0)->getType());
auto *IntTy =
dyn_cast<IntegerType>(I.getOperand(0)->getType()->getScalarType());
if (IntTy->getIntegerBitWidth() <= MaxLegalFpConvertBitWidth)
continue;

Replace.push_back(&I);
if (I.getOperand(0)->getType()->isVectorTy())
ReplaceVector.push_back(&I);
else
Replace.push_back(&I);
Modified = true;
break;
}
Expand All @@ -615,6 +643,11 @@ static bool runImpl(Function &F, const TargetLowering &TLI) {
}
}

while (!ReplaceVector.empty()) {
Instruction *I = ReplaceVector.pop_back_val();
scalarize(I, Replace);
}

if (Replace.empty())
return false;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,80 @@ define i129 @fp128tosi129(fp128 %a) {
%conv = fptosi fp128 %a to i129
ret i129 %conv
}

define <2 x i129> @floattosi129v2(<2 x float> %a) {
; CHECK-LABEL: @floattosi129v2(
; CHECK-NEXT: fp-to-i-entryfp-to-i-entry:
; CHECK-NEXT: [[TMP0:%.*]] = extractelement <2 x float> [[A:%.*]], i64 0
; CHECK-NEXT: [[TMP1:%.*]] = bitcast float [[TMP0]] to i32
; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[TMP1]] to i129
; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP1]], -1
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i129 1, i129 -1
; CHECK-NEXT: [[TMP5:%.*]] = lshr i129 [[TMP2]], 23
; CHECK-NEXT: [[TMP6:%.*]] = and i129 [[TMP5]], 255
; CHECK-NEXT: [[TMP7:%.*]] = and i129 [[TMP2]], 8388607
; CHECK-NEXT: [[TMP8:%.*]] = or i129 [[TMP7]], 8388608
; CHECK-NEXT: [[TMP9:%.*]] = icmp ult i129 [[TMP6]], 127
; CHECK-NEXT: br i1 [[TMP9]], label [[FP_TO_I_CLEANUP1:%.*]], label [[FP_TO_I_IF_END2:%.*]]
; CHECK: fp-to-i-if-end2:
; CHECK-NEXT: [[TMP10:%.*]] = add i129 [[TMP6]], -256
; CHECK-NEXT: [[TMP11:%.*]] = icmp ult i129 [[TMP10]], -129
; CHECK-NEXT: br i1 [[TMP11]], label [[FP_TO_I_IF_THEN53:%.*]], label [[FP_TO_I_IF_END94:%.*]]
; CHECK: fp-to-i-if-then53:
; CHECK-NEXT: [[TMP12:%.*]] = select i1 [[TMP3]], i129 340282366920938463463374607431768211455, i129 -340282366920938463463374607431768211456
; CHECK-NEXT: br label [[FP_TO_I_CLEANUP1]]
; CHECK: fp-to-i-if-end94:
; CHECK-NEXT: [[TMP13:%.*]] = icmp ult i129 [[TMP6]], 150
; CHECK-NEXT: br i1 [[TMP13]], label [[FP_TO_I_IF_THEN125:%.*]], label [[FP_TO_I_IF_ELSE6:%.*]]
; CHECK: fp-to-i-if-then125:
; CHECK-NEXT: [[TMP14:%.*]] = sub i129 150, [[TMP6]]
; CHECK-NEXT: [[TMP15:%.*]] = lshr i129 [[TMP8]], [[TMP14]]
; CHECK-NEXT: [[TMP16:%.*]] = mul i129 [[TMP15]], [[TMP4]]
; CHECK-NEXT: br label [[FP_TO_I_CLEANUP1]]
; CHECK: fp-to-i-if-else6:
; CHECK-NEXT: [[TMP17:%.*]] = add i129 [[TMP6]], -150
; CHECK-NEXT: [[TMP18:%.*]] = shl i129 [[TMP8]], [[TMP17]]
; CHECK-NEXT: [[TMP19:%.*]] = mul i129 [[TMP18]], [[TMP4]]
; CHECK-NEXT: br label [[FP_TO_I_CLEANUP1]]
; CHECK: fp-to-i-cleanup1:
; CHECK-NEXT: [[TMP20:%.*]] = phi i129 [ [[TMP12]], [[FP_TO_I_IF_THEN53]] ], [ [[TMP16]], [[FP_TO_I_IF_THEN125]] ], [ [[TMP19]], [[FP_TO_I_IF_ELSE6]] ], [ 0, [[FP_TO_I_ENTRYFP_TO_I_ENTRY:%.*]] ]
; CHECK-NEXT: [[TMP21:%.*]] = insertelement <2 x i129> poison, i129 [[TMP20]], i64 0
; CHECK-NEXT: [[TMP22:%.*]] = extractelement <2 x float> [[A]], i64 1
; CHECK-NEXT: [[TMP23:%.*]] = bitcast float [[TMP22]] to i32
; CHECK-NEXT: [[TMP24:%.*]] = zext i32 [[TMP23]] to i129
; CHECK-NEXT: [[TMP25:%.*]] = icmp sgt i32 [[TMP23]], -1
; CHECK-NEXT: [[TMP26:%.*]] = select i1 [[TMP25]], i129 1, i129 -1
; CHECK-NEXT: [[TMP27:%.*]] = lshr i129 [[TMP24]], 23
; CHECK-NEXT: [[TMP28:%.*]] = and i129 [[TMP27]], 255
; CHECK-NEXT: [[TMP29:%.*]] = and i129 [[TMP24]], 8388607
; CHECK-NEXT: [[TMP30:%.*]] = or i129 [[TMP29]], 8388608
; CHECK-NEXT: [[TMP31:%.*]] = icmp ult i129 [[TMP28]], 127
; CHECK-NEXT: br i1 [[TMP31]], label [[FP_TO_I_CLEANUP:%.*]], label [[FP_TO_I_IF_END:%.*]]
; CHECK: fp-to-i-if-end:
; CHECK-NEXT: [[TMP32:%.*]] = add i129 [[TMP28]], -256
; CHECK-NEXT: [[TMP33:%.*]] = icmp ult i129 [[TMP32]], -129
; CHECK-NEXT: br i1 [[TMP33]], label [[FP_TO_I_IF_THEN5:%.*]], label [[FP_TO_I_IF_END9:%.*]]
; CHECK: fp-to-i-if-then5:
; CHECK-NEXT: [[TMP34:%.*]] = select i1 [[TMP25]], i129 340282366920938463463374607431768211455, i129 -340282366920938463463374607431768211456
; CHECK-NEXT: br label [[FP_TO_I_CLEANUP]]
; CHECK: fp-to-i-if-end9:
; CHECK-NEXT: [[TMP35:%.*]] = icmp ult i129 [[TMP28]], 150
; CHECK-NEXT: br i1 [[TMP35]], label [[FP_TO_I_IF_THEN12:%.*]], label [[FP_TO_I_IF_ELSE:%.*]]
; CHECK: fp-to-i-if-then12:
; CHECK-NEXT: [[TMP36:%.*]] = sub i129 150, [[TMP28]]
; CHECK-NEXT: [[TMP37:%.*]] = lshr i129 [[TMP30]], [[TMP36]]
; CHECK-NEXT: [[TMP38:%.*]] = mul i129 [[TMP37]], [[TMP26]]
; CHECK-NEXT: br label [[FP_TO_I_CLEANUP]]
; CHECK: fp-to-i-if-else:
; CHECK-NEXT: [[TMP39:%.*]] = add i129 [[TMP28]], -150
; CHECK-NEXT: [[TMP40:%.*]] = shl i129 [[TMP30]], [[TMP39]]
; CHECK-NEXT: [[TMP41:%.*]] = mul i129 [[TMP40]], [[TMP26]]
; CHECK-NEXT: br label [[FP_TO_I_CLEANUP]]
; CHECK: fp-to-i-cleanup:
; CHECK-NEXT: [[TMP42:%.*]] = phi i129 [ [[TMP34]], [[FP_TO_I_IF_THEN5]] ], [ [[TMP38]], [[FP_TO_I_IF_THEN12]] ], [ [[TMP41]], [[FP_TO_I_IF_ELSE]] ], [ 0, [[FP_TO_I_CLEANUP1]] ]
; CHECK-NEXT: [[TMP43:%.*]] = insertelement <2 x i129> [[TMP21]], i129 [[TMP42]], i64 1
; CHECK-NEXT: ret <2 x i129> [[TMP43]]
;
%conv = fptosi <2 x float> %a to <2 x i129>
ret <2 x i129> %conv
}
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,80 @@ define i129 @fp128toui129(fp128 %a) {
%conv = fptoui fp128 %a to i129
ret i129 %conv
}

define <2 x i129> @floattoui129v2(<2 x float> %a) {
; CHECK-LABEL: @floattoui129v2(
; CHECK-NEXT: fp-to-i-entryfp-to-i-entry:
; CHECK-NEXT: [[TMP0:%.*]] = extractelement <2 x float> [[A:%.*]], i64 0
; CHECK-NEXT: [[TMP1:%.*]] = bitcast float [[TMP0]] to i32
; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[TMP1]] to i129
; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP1]], -1
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i129 1, i129 -1
; CHECK-NEXT: [[TMP5:%.*]] = lshr i129 [[TMP2]], 23
; CHECK-NEXT: [[TMP6:%.*]] = and i129 [[TMP5]], 255
; CHECK-NEXT: [[TMP7:%.*]] = and i129 [[TMP2]], 8388607
; CHECK-NEXT: [[TMP8:%.*]] = or i129 [[TMP7]], 8388608
; CHECK-NEXT: [[TMP9:%.*]] = icmp ult i129 [[TMP6]], 127
; CHECK-NEXT: br i1 [[TMP9]], label [[FP_TO_I_CLEANUP1:%.*]], label [[FP_TO_I_IF_END2:%.*]]
; CHECK: fp-to-i-if-end2:
; CHECK-NEXT: [[TMP10:%.*]] = add i129 [[TMP6]], -256
; CHECK-NEXT: [[TMP11:%.*]] = icmp ult i129 [[TMP10]], -129
; CHECK-NEXT: br i1 [[TMP11]], label [[FP_TO_I_IF_THEN53:%.*]], label [[FP_TO_I_IF_END94:%.*]]
; CHECK: fp-to-i-if-then53:
; CHECK-NEXT: [[TMP12:%.*]] = select i1 [[TMP3]], i129 340282366920938463463374607431768211455, i129 -340282366920938463463374607431768211456
; CHECK-NEXT: br label [[FP_TO_I_CLEANUP1]]
; CHECK: fp-to-i-if-end94:
; CHECK-NEXT: [[TMP13:%.*]] = icmp ult i129 [[TMP6]], 150
; CHECK-NEXT: br i1 [[TMP13]], label [[FP_TO_I_IF_THEN125:%.*]], label [[FP_TO_I_IF_ELSE6:%.*]]
; CHECK: fp-to-i-if-then125:
; CHECK-NEXT: [[TMP14:%.*]] = sub i129 150, [[TMP6]]
; CHECK-NEXT: [[TMP15:%.*]] = lshr i129 [[TMP8]], [[TMP14]]
; CHECK-NEXT: [[TMP16:%.*]] = mul i129 [[TMP15]], [[TMP4]]
; CHECK-NEXT: br label [[FP_TO_I_CLEANUP1]]
; CHECK: fp-to-i-if-else6:
; CHECK-NEXT: [[TMP17:%.*]] = add i129 [[TMP6]], -150
; CHECK-NEXT: [[TMP18:%.*]] = shl i129 [[TMP8]], [[TMP17]]
; CHECK-NEXT: [[TMP19:%.*]] = mul i129 [[TMP18]], [[TMP4]]
; CHECK-NEXT: br label [[FP_TO_I_CLEANUP1]]
; CHECK: fp-to-i-cleanup1:
; CHECK-NEXT: [[TMP20:%.*]] = phi i129 [ [[TMP12]], [[FP_TO_I_IF_THEN53]] ], [ [[TMP16]], [[FP_TO_I_IF_THEN125]] ], [ [[TMP19]], [[FP_TO_I_IF_ELSE6]] ], [ 0, [[FP_TO_I_ENTRYFP_TO_I_ENTRY:%.*]] ]
; CHECK-NEXT: [[TMP21:%.*]] = insertelement <2 x i129> poison, i129 [[TMP20]], i64 0
; CHECK-NEXT: [[TMP22:%.*]] = extractelement <2 x float> [[A]], i64 1
; CHECK-NEXT: [[TMP23:%.*]] = bitcast float [[TMP22]] to i32
; CHECK-NEXT: [[TMP24:%.*]] = zext i32 [[TMP23]] to i129
; CHECK-NEXT: [[TMP25:%.*]] = icmp sgt i32 [[TMP23]], -1
; CHECK-NEXT: [[TMP26:%.*]] = select i1 [[TMP25]], i129 1, i129 -1
; CHECK-NEXT: [[TMP27:%.*]] = lshr i129 [[TMP24]], 23
; CHECK-NEXT: [[TMP28:%.*]] = and i129 [[TMP27]], 255
; CHECK-NEXT: [[TMP29:%.*]] = and i129 [[TMP24]], 8388607
; CHECK-NEXT: [[TMP30:%.*]] = or i129 [[TMP29]], 8388608
; CHECK-NEXT: [[TMP31:%.*]] = icmp ult i129 [[TMP28]], 127
; CHECK-NEXT: br i1 [[TMP31]], label [[FP_TO_I_CLEANUP:%.*]], label [[FP_TO_I_IF_END:%.*]]
; CHECK: fp-to-i-if-end:
; CHECK-NEXT: [[TMP32:%.*]] = add i129 [[TMP28]], -256
; CHECK-NEXT: [[TMP33:%.*]] = icmp ult i129 [[TMP32]], -129
; CHECK-NEXT: br i1 [[TMP33]], label [[FP_TO_I_IF_THEN5:%.*]], label [[FP_TO_I_IF_END9:%.*]]
; CHECK: fp-to-i-if-then5:
; CHECK-NEXT: [[TMP34:%.*]] = select i1 [[TMP25]], i129 340282366920938463463374607431768211455, i129 -340282366920938463463374607431768211456
; CHECK-NEXT: br label [[FP_TO_I_CLEANUP]]
; CHECK: fp-to-i-if-end9:
; CHECK-NEXT: [[TMP35:%.*]] = icmp ult i129 [[TMP28]], 150
; CHECK-NEXT: br i1 [[TMP35]], label [[FP_TO_I_IF_THEN12:%.*]], label [[FP_TO_I_IF_ELSE:%.*]]
; CHECK: fp-to-i-if-then12:
; CHECK-NEXT: [[TMP36:%.*]] = sub i129 150, [[TMP28]]
; CHECK-NEXT: [[TMP37:%.*]] = lshr i129 [[TMP30]], [[TMP36]]
; CHECK-NEXT: [[TMP38:%.*]] = mul i129 [[TMP37]], [[TMP26]]
; CHECK-NEXT: br label [[FP_TO_I_CLEANUP]]
; CHECK: fp-to-i-if-else:
; CHECK-NEXT: [[TMP39:%.*]] = add i129 [[TMP28]], -150
; CHECK-NEXT: [[TMP40:%.*]] = shl i129 [[TMP30]], [[TMP39]]
; CHECK-NEXT: [[TMP41:%.*]] = mul i129 [[TMP40]], [[TMP26]]
; CHECK-NEXT: br label [[FP_TO_I_CLEANUP]]
; CHECK: fp-to-i-cleanup:
; CHECK-NEXT: [[TMP42:%.*]] = phi i129 [ [[TMP34]], [[FP_TO_I_IF_THEN5]] ], [ [[TMP38]], [[FP_TO_I_IF_THEN12]] ], [ [[TMP41]], [[FP_TO_I_IF_ELSE]] ], [ 0, [[FP_TO_I_CLEANUP1]] ]
; CHECK-NEXT: [[TMP43:%.*]] = insertelement <2 x i129> [[TMP21]], i129 [[TMP42]], i64 1
; CHECK-NEXT: ret <2 x i129> [[TMP43]]
;
%conv = fptoui <2 x float> %a to <2 x i129>
ret <2 x i129> %conv
}

0 comments on commit 7edddee

Please sign in to comment.