diff --git a/llvm/include/llvm/Transforms/Scalar/Float2Int.h b/llvm/include/llvm/Transforms/Scalar/Float2Int.h index 83be329bed60b..337e229efcf37 100644 --- a/llvm/include/llvm/Transforms/Scalar/Float2Int.h +++ b/llvm/include/llvm/Transforms/Scalar/Float2Int.h @@ -44,7 +44,7 @@ class Float2IntPass : public PassInfoMixin { std::optional calcRange(Instruction *I); void walkBackwards(); void walkForwards(); - bool validateAndTransform(); + bool validateAndTransform(const DataLayout &DL); Value *convert(Instruction *I, Type *ToTy); void cleanup(); diff --git a/llvm/lib/Transforms/Scalar/Float2Int.cpp b/llvm/lib/Transforms/Scalar/Float2Int.cpp index ccca8bcc1a56a..6ad4be169b589 100644 --- a/llvm/lib/Transforms/Scalar/Float2Int.cpp +++ b/llvm/lib/Transforms/Scalar/Float2Int.cpp @@ -311,7 +311,7 @@ void Float2IntPass::walkForwards() { } // If there is a valid transform to be done, do it. -bool Float2IntPass::validateAndTransform() { +bool Float2IntPass::validateAndTransform(const DataLayout &DL) { bool MadeChange = false; // Iterate over every disjoint partition of the def-use graph. @@ -376,15 +376,23 @@ bool Float2IntPass::validateAndTransform() { LLVM_DEBUG(dbgs() << "F2I: Value not guaranteed to be representable!\n"); continue; } - if (MinBW > 64) { - LLVM_DEBUG( - dbgs() << "F2I: Value requires more than 64 bits to represent!\n"); - continue; - } - // OK, R is known to be representable. Now pick a type for it. - // FIXME: Pick the smallest legal type that will fit. - Type *Ty = (MinBW > 32) ? Type::getInt64Ty(*Ctx) : Type::getInt32Ty(*Ctx); + // OK, R is known to be representable. + // Pick the smallest legal type that will fit. + Type *Ty = DL.getSmallestLegalIntType(*Ctx, MinBW); + if (!Ty) { + // Every supported target supports 64-bit and 32-bit integers, + // so fallback to a 32 or 64-bit integer if the value fits. + if (MinBW <= 32) { + Ty = Type::getInt32Ty(*Ctx); + } else if (MinBW <= 64) { + Ty = Type::getInt64Ty(*Ctx); + } else { + LLVM_DEBUG(dbgs() << "F2I: Value requires more than bits to represent " + "than the target supports!\n"); + continue; + } + } for (auto MI = ECs.member_begin(It), ME = ECs.member_end(); MI != ME; ++MI) @@ -491,7 +499,8 @@ bool Float2IntPass::runImpl(Function &F, const DominatorTree &DT) { walkBackwards(); walkForwards(); - bool Modified = validateAndTransform(); + const DataLayout &DL = F.getParent()->getDataLayout(); + bool Modified = validateAndTransform(DL); if (Modified) cleanup(); return Modified; diff --git a/llvm/test/Transforms/Float2Int/basic.ll b/llvm/test/Transforms/Float2Int/basic.ll index 2854a83179b7e..a454b773f4eba 100644 --- a/llvm/test/Transforms/Float2Int/basic.ll +++ b/llvm/test/Transforms/Float2Int/basic.ll @@ -1,16 +1,29 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -passes='float2int' -S | FileCheck %s +; RUN: opt < %s -passes=float2int -S | FileCheck %s -check-prefixes=CHECK,NONE +; RUN: opt < %s -passes=float2int -S --data-layout="n64" | FileCheck %s -check-prefixes=CHECK,ONLY64 +; RUN: opt < %s -passes=float2int -S --data-layout="n8:16:32:64"| FileCheck %s -check-prefixes=CHECK,MULTIPLE ; ; Positive tests ; define i16 @simple1(i8 %a) { -; CHECK-LABEL: @simple1( -; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 -; CHECK-NEXT: [[T21:%.*]] = add i32 [[TMP1]], 1 -; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i16 -; CHECK-NEXT: ret i16 [[TMP2]] +; NONE-LABEL: @simple1( +; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 +; NONE-NEXT: [[T21:%.*]] = add i32 [[TMP1]], 1 +; NONE-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i16 +; NONE-NEXT: ret i16 [[TMP2]] +; +; ONLY64-LABEL: @simple1( +; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 +; ONLY64-NEXT: [[T21:%.*]] = add i64 [[TMP1]], 1 +; ONLY64-NEXT: [[TMP2:%.*]] = trunc i64 [[T21]] to i16 +; ONLY64-NEXT: ret i16 [[TMP2]] +; +; MULTIPLE-LABEL: @simple1( +; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 +; MULTIPLE-NEXT: [[T21:%.*]] = add i16 [[TMP1]], 1 +; MULTIPLE-NEXT: ret i16 [[T21]] ; %t1 = uitofp i8 %a to float %t2 = fadd float %t1, 1.0 @@ -19,11 +32,23 @@ define i16 @simple1(i8 %a) { } define i8 @simple2(i8 %a) { -; CHECK-LABEL: @simple2( -; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 -; CHECK-NEXT: [[T21:%.*]] = sub i32 [[TMP1]], 1 -; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i8 -; CHECK-NEXT: ret i8 [[TMP2]] +; NONE-LABEL: @simple2( +; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 +; NONE-NEXT: [[T21:%.*]] = sub i32 [[TMP1]], 1 +; NONE-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i8 +; NONE-NEXT: ret i8 [[TMP2]] +; +; ONLY64-LABEL: @simple2( +; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 +; ONLY64-NEXT: [[T21:%.*]] = sub i64 [[TMP1]], 1 +; ONLY64-NEXT: [[TMP2:%.*]] = trunc i64 [[T21]] to i8 +; ONLY64-NEXT: ret i8 [[TMP2]] +; +; MULTIPLE-LABEL: @simple2( +; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 +; MULTIPLE-NEXT: [[T21:%.*]] = sub i16 [[TMP1]], 1 +; MULTIPLE-NEXT: [[TMP2:%.*]] = trunc i16 [[T21]] to i8 +; MULTIPLE-NEXT: ret i8 [[TMP2]] ; %t1 = uitofp i8 %a to float %t2 = fsub float %t1, 1.0 @@ -32,10 +57,22 @@ define i8 @simple2(i8 %a) { } define i32 @simple3(i8 %a) { -; CHECK-LABEL: @simple3( -; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 -; CHECK-NEXT: [[T21:%.*]] = sub i32 [[TMP1]], 1 -; CHECK-NEXT: ret i32 [[T21]] +; NONE-LABEL: @simple3( +; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 +; NONE-NEXT: [[T21:%.*]] = sub i32 [[TMP1]], 1 +; NONE-NEXT: ret i32 [[T21]] +; +; ONLY64-LABEL: @simple3( +; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 +; ONLY64-NEXT: [[T21:%.*]] = sub i64 [[TMP1]], 1 +; ONLY64-NEXT: [[TMP2:%.*]] = trunc i64 [[T21]] to i32 +; ONLY64-NEXT: ret i32 [[TMP2]] +; +; MULTIPLE-LABEL: @simple3( +; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 +; MULTIPLE-NEXT: [[T21:%.*]] = sub i16 [[TMP1]], 1 +; MULTIPLE-NEXT: [[TMP2:%.*]] = zext i16 [[T21]] to i32 +; MULTIPLE-NEXT: ret i32 [[TMP2]] ; %t1 = uitofp i8 %a to float %t2 = fsub float %t1, 1.0 @@ -44,11 +81,23 @@ define i32 @simple3(i8 %a) { } define i1 @cmp(i8 %a, i8 %b) { -; CHECK-LABEL: @cmp( -; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 -; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 -; CHECK-NEXT: [[T31:%.*]] = icmp slt i32 [[TMP1]], [[TMP2]] -; CHECK-NEXT: ret i1 [[T31]] +; NONE-LABEL: @cmp( +; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 +; NONE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 +; NONE-NEXT: [[T31:%.*]] = icmp slt i32 [[TMP1]], [[TMP2]] +; NONE-NEXT: ret i1 [[T31]] +; +; ONLY64-LABEL: @cmp( +; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 +; ONLY64-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i64 +; ONLY64-NEXT: [[T31:%.*]] = icmp slt i64 [[TMP1]], [[TMP2]] +; ONLY64-NEXT: ret i1 [[T31]] +; +; MULTIPLE-LABEL: @cmp( +; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 +; MULTIPLE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i16 +; MULTIPLE-NEXT: [[T31:%.*]] = icmp slt i16 [[TMP1]], [[TMP2]] +; MULTIPLE-NEXT: ret i1 [[T31]] ; %t1 = uitofp i8 %a to float %t2 = uitofp i8 %b to float @@ -70,12 +119,27 @@ define i32 @simple4(i32 %a) { } define i32 @simple5(i8 %a, i8 %b) { -; CHECK-LABEL: @simple5( -; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 -; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 -; CHECK-NEXT: [[T31:%.*]] = add i32 [[TMP1]], 1 -; CHECK-NEXT: [[T42:%.*]] = mul i32 [[T31]], [[TMP2]] -; CHECK-NEXT: ret i32 [[T42]] +; NONE-LABEL: @simple5( +; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 +; NONE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 +; NONE-NEXT: [[T31:%.*]] = add i32 [[TMP1]], 1 +; NONE-NEXT: [[T42:%.*]] = mul i32 [[T31]], [[TMP2]] +; NONE-NEXT: ret i32 [[T42]] +; +; ONLY64-LABEL: @simple5( +; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 +; ONLY64-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i64 +; ONLY64-NEXT: [[T31:%.*]] = add i64 [[TMP1]], 1 +; ONLY64-NEXT: [[T42:%.*]] = mul i64 [[T31]], [[TMP2]] +; ONLY64-NEXT: [[TMP3:%.*]] = trunc i64 [[T42]] to i32 +; ONLY64-NEXT: ret i32 [[TMP3]] +; +; MULTIPLE-LABEL: @simple5( +; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 +; MULTIPLE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 +; MULTIPLE-NEXT: [[T31:%.*]] = add i32 [[TMP1]], 1 +; MULTIPLE-NEXT: [[T42:%.*]] = mul i32 [[T31]], [[TMP2]] +; MULTIPLE-NEXT: ret i32 [[T42]] ; %t1 = uitofp i8 %a to float %t2 = uitofp i8 %b to float @@ -86,12 +150,27 @@ define i32 @simple5(i8 %a, i8 %b) { } define i32 @simple6(i8 %a, i8 %b) { -; CHECK-LABEL: @simple6( -; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 -; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 -; CHECK-NEXT: [[T31:%.*]] = sub i32 0, [[TMP1]] -; CHECK-NEXT: [[T42:%.*]] = mul i32 [[T31]], [[TMP2]] -; CHECK-NEXT: ret i32 [[T42]] +; NONE-LABEL: @simple6( +; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 +; NONE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 +; NONE-NEXT: [[T31:%.*]] = sub i32 0, [[TMP1]] +; NONE-NEXT: [[T42:%.*]] = mul i32 [[T31]], [[TMP2]] +; NONE-NEXT: ret i32 [[T42]] +; +; ONLY64-LABEL: @simple6( +; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 +; ONLY64-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i64 +; ONLY64-NEXT: [[T31:%.*]] = sub i64 0, [[TMP1]] +; ONLY64-NEXT: [[T42:%.*]] = mul i64 [[T31]], [[TMP2]] +; ONLY64-NEXT: [[TMP3:%.*]] = trunc i64 [[T42]] to i32 +; ONLY64-NEXT: ret i32 [[TMP3]] +; +; MULTIPLE-LABEL: @simple6( +; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 +; MULTIPLE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 +; MULTIPLE-NEXT: [[T31:%.*]] = sub i32 0, [[TMP1]] +; MULTIPLE-NEXT: [[T42:%.*]] = mul i32 [[T31]], [[TMP2]] +; MULTIPLE-NEXT: ret i32 [[T42]] ; %t1 = uitofp i8 %a to float %t2 = uitofp i8 %b to float @@ -105,15 +184,37 @@ define i32 @simple6(i8 %a, i8 %b) { ; cause failure of the other. define i32 @multi1(i8 %a, i8 %b, i8 %c, float %d) { -; CHECK-LABEL: @multi1( -; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 -; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 -; CHECK-NEXT: [[FC:%.*]] = uitofp i8 [[C:%.*]] to float -; CHECK-NEXT: [[X1:%.*]] = add i32 [[TMP1]], [[TMP2]] -; CHECK-NEXT: [[Z:%.*]] = fadd float [[FC]], [[D:%.*]] -; CHECK-NEXT: [[W:%.*]] = fptoui float [[Z]] to i32 -; CHECK-NEXT: [[R:%.*]] = add i32 [[X1]], [[W]] -; CHECK-NEXT: ret i32 [[R]] +; NONE-LABEL: @multi1( +; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 +; NONE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 +; NONE-NEXT: [[FC:%.*]] = uitofp i8 [[C:%.*]] to float +; NONE-NEXT: [[X1:%.*]] = add i32 [[TMP1]], [[TMP2]] +; NONE-NEXT: [[Z:%.*]] = fadd float [[FC]], [[D:%.*]] +; NONE-NEXT: [[W:%.*]] = fptoui float [[Z]] to i32 +; NONE-NEXT: [[R:%.*]] = add i32 [[X1]], [[W]] +; NONE-NEXT: ret i32 [[R]] +; +; ONLY64-LABEL: @multi1( +; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 +; ONLY64-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i64 +; ONLY64-NEXT: [[FC:%.*]] = uitofp i8 [[C:%.*]] to float +; ONLY64-NEXT: [[X1:%.*]] = add i64 [[TMP1]], [[TMP2]] +; ONLY64-NEXT: [[TMP3:%.*]] = trunc i64 [[X1]] to i32 +; ONLY64-NEXT: [[Z:%.*]] = fadd float [[FC]], [[D:%.*]] +; ONLY64-NEXT: [[W:%.*]] = fptoui float [[Z]] to i32 +; ONLY64-NEXT: [[R:%.*]] = add i32 [[TMP3]], [[W]] +; ONLY64-NEXT: ret i32 [[R]] +; +; MULTIPLE-LABEL: @multi1( +; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 +; MULTIPLE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i16 +; MULTIPLE-NEXT: [[FC:%.*]] = uitofp i8 [[C:%.*]] to float +; MULTIPLE-NEXT: [[X1:%.*]] = add i16 [[TMP1]], [[TMP2]] +; MULTIPLE-NEXT: [[TMP3:%.*]] = zext i16 [[X1]] to i32 +; MULTIPLE-NEXT: [[Z:%.*]] = fadd float [[FC]], [[D:%.*]] +; MULTIPLE-NEXT: [[W:%.*]] = fptoui float [[Z]] to i32 +; MULTIPLE-NEXT: [[R:%.*]] = add i32 [[TMP3]], [[W]] +; MULTIPLE-NEXT: ret i32 [[R]] ; %fa = uitofp i8 %a to float %fb = uitofp i8 %b to float @@ -127,11 +228,22 @@ define i32 @multi1(i8 %a, i8 %b, i8 %c, float %d) { } define i16 @simple_negzero(i8 %a) { -; CHECK-LABEL: @simple_negzero( -; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 -; CHECK-NEXT: [[T21:%.*]] = add i32 [[TMP1]], 0 -; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i16 -; CHECK-NEXT: ret i16 [[TMP2]] +; NONE-LABEL: @simple_negzero( +; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 +; NONE-NEXT: [[T21:%.*]] = add i32 [[TMP1]], 0 +; NONE-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i16 +; NONE-NEXT: ret i16 [[TMP2]] +; +; ONLY64-LABEL: @simple_negzero( +; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 +; ONLY64-NEXT: [[T21:%.*]] = add i64 [[TMP1]], 0 +; ONLY64-NEXT: [[TMP2:%.*]] = trunc i64 [[T21]] to i16 +; ONLY64-NEXT: ret i16 [[TMP2]] +; +; MULTIPLE-LABEL: @simple_negzero( +; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 +; MULTIPLE-NEXT: [[T21:%.*]] = add i16 [[TMP1]], 0 +; MULTIPLE-NEXT: ret i16 [[T21]] ; %t1 = uitofp i8 %a to float %t2 = fadd fast float %t1, -0.0 @@ -140,12 +252,26 @@ define i16 @simple_negzero(i8 %a) { } define i32 @simple_negative(i8 %call) { -; CHECK-LABEL: @simple_negative( -; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[CALL:%.*]] to i32 -; CHECK-NEXT: [[MUL1:%.*]] = mul i32 [[TMP1]], -3 -; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[MUL1]] to i8 -; CHECK-NEXT: [[CONV3:%.*]] = sext i8 [[TMP2]] to i32 -; CHECK-NEXT: ret i32 [[CONV3]] +; NONE-LABEL: @simple_negative( +; NONE-NEXT: [[TMP1:%.*]] = sext i8 [[CALL:%.*]] to i32 +; NONE-NEXT: [[MUL1:%.*]] = mul i32 [[TMP1]], -3 +; NONE-NEXT: [[TMP2:%.*]] = trunc i32 [[MUL1]] to i8 +; NONE-NEXT: [[CONV3:%.*]] = sext i8 [[TMP2]] to i32 +; NONE-NEXT: ret i32 [[CONV3]] +; +; ONLY64-LABEL: @simple_negative( +; ONLY64-NEXT: [[TMP1:%.*]] = sext i8 [[CALL:%.*]] to i64 +; ONLY64-NEXT: [[MUL1:%.*]] = mul i64 [[TMP1]], -3 +; ONLY64-NEXT: [[TMP2:%.*]] = trunc i64 [[MUL1]] to i8 +; ONLY64-NEXT: [[CONV3:%.*]] = sext i8 [[TMP2]] to i32 +; ONLY64-NEXT: ret i32 [[CONV3]] +; +; MULTIPLE-LABEL: @simple_negative( +; MULTIPLE-NEXT: [[TMP1:%.*]] = sext i8 [[CALL:%.*]] to i16 +; MULTIPLE-NEXT: [[MUL1:%.*]] = mul i16 [[TMP1]], -3 +; MULTIPLE-NEXT: [[TMP2:%.*]] = trunc i16 [[MUL1]] to i8 +; MULTIPLE-NEXT: [[CONV3:%.*]] = sext i8 [[TMP2]] to i32 +; MULTIPLE-NEXT: ret i32 [[CONV3]] ; %conv1 = sitofp i8 %call to float %mul = fmul float %conv1, -3.000000e+00 @@ -155,11 +281,22 @@ define i32 @simple_negative(i8 %call) { } define i16 @simple_fneg(i8 %a) { -; CHECK-LABEL: @simple_fneg( -; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 -; CHECK-NEXT: [[T21:%.*]] = sub i32 0, [[TMP1]] -; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i16 -; CHECK-NEXT: ret i16 [[TMP2]] +; NONE-LABEL: @simple_fneg( +; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 +; NONE-NEXT: [[T21:%.*]] = sub i32 0, [[TMP1]] +; NONE-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i16 +; NONE-NEXT: ret i16 [[TMP2]] +; +; ONLY64-LABEL: @simple_fneg( +; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 +; ONLY64-NEXT: [[T21:%.*]] = sub i64 0, [[TMP1]] +; ONLY64-NEXT: [[TMP2:%.*]] = trunc i64 [[T21]] to i16 +; ONLY64-NEXT: ret i16 [[TMP2]] +; +; MULTIPLE-LABEL: @simple_fneg( +; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 +; MULTIPLE-NEXT: [[T21:%.*]] = sub i16 0, [[TMP1]] +; MULTIPLE-NEXT: ret i16 [[T21]] ; %t1 = uitofp i8 %a to float %t2 = fneg fast float %t1