diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
--- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -191,8 +191,7 @@
 
   // If we are casting an integer to vector and extracting a portion, that is
   // a shift-right and truncate.
-  // TODO: Allow FP dest type by casting the trunc to FP?
-  if (X->getType()->isIntegerTy() && DestTy->isIntegerTy() &&
+  if (X->getType()->isIntegerTy() &&
       isDesirableIntType(X->getType()->getPrimitiveSizeInBits())) {
     assert(isa<FixedVectorType>(Ext.getVectorOperand()->getType()) &&
            "Expected fixed vector type for bitcast from scalar integer");
@@ -205,6 +204,12 @@
     unsigned ShiftAmountC = ExtIndexC * DestTy->getPrimitiveSizeInBits();
     if (!ShiftAmountC || Ext.getVectorOperand()->hasOneUse()) {
       Value *Lshr = Builder.CreateLShr(X, ShiftAmountC, "extelt.offset");
+      if (DestTy->isFloatingPointTy()) {
+        Type *DstIntTy = IntegerType::getIntNTy(
+            Lshr->getContext(), DestTy->getPrimitiveSizeInBits());
+        Value *Trunc = Builder.CreateTrunc(Lshr, DstIntTy);
+        return new BitCastInst(Trunc, DestTy);
+      }
       return new TruncInst(Lshr, DestTy);
     }
   }
diff --git a/llvm/test/Transforms/InstCombine/extractelement.ll b/llvm/test/Transforms/InstCombine/extractelement.ll
--- a/llvm/test/Transforms/InstCombine/extractelement.ll
+++ b/llvm/test/Transforms/InstCombine/extractelement.ll
@@ -527,10 +527,27 @@
 }
 
 define half @bitcast_fp16vec_index0(i32 %x) {
-; ANY-LABEL: @bitcast_fp16vec_index0(
-; ANY-NEXT:    [[V:%.*]] = bitcast i32 [[X:%.*]] to <2 x half>
-; ANY-NEXT:    [[R:%.*]] = extractelement <2 x half> [[V]], i64 0
-; ANY-NEXT:    ret half [[R]]
+; LE64-LABEL: @bitcast_fp16vec_index0(
+; LE64-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
+; LE64-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to half
+; LE64-NEXT:    ret half [[R]]
+;
+; BE64-LABEL: @bitcast_fp16vec_index0(
+; BE64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16
+; BE64-NEXT:    [[TMP1:%.*]] = trunc i32 [[EXTELT_OFFSET]] to i16
+; BE64-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to half
+; BE64-NEXT:    ret half [[R]]
+;
+; LE128-LABEL: @bitcast_fp16vec_index0(
+; LE128-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
+; LE128-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to half
+; LE128-NEXT:    ret half [[R]]
+;
+; BE128-LABEL: @bitcast_fp16vec_index0(
+; BE128-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16
+; BE128-NEXT:    [[TMP1:%.*]] = trunc i32 [[EXTELT_OFFSET]] to i16
+; BE128-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to half
+; BE128-NEXT:    ret half [[R]]
 ;
   %v = bitcast i32 %x to <2 x half>
   %r = extractelement <2 x half> %v, i8 0
@@ -538,10 +555,27 @@
 }
 
 define half @bitcast_fp16vec_index1(i32 %x) {
-; ANY-LABEL: @bitcast_fp16vec_index1(
-; ANY-NEXT:    [[V:%.*]] = bitcast i32 [[X:%.*]] to <2 x half>
-; ANY-NEXT:    [[R:%.*]] = extractelement <2 x half> [[V]], i64 1
-; ANY-NEXT:    ret half [[R]]
+; LE64-LABEL: @bitcast_fp16vec_index1(
+; LE64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16
+; LE64-NEXT:    [[TMP1:%.*]] = trunc i32 [[EXTELT_OFFSET]] to i16
+; LE64-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to half
+; LE64-NEXT:    ret half [[R]]
+;
+; BE64-LABEL: @bitcast_fp16vec_index1(
+; BE64-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
+; BE64-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to half
+; BE64-NEXT:    ret half [[R]]
+;
+; LE128-LABEL: @bitcast_fp16vec_index1(
+; LE128-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16
+; LE128-NEXT:    [[TMP1:%.*]] = trunc i32 [[EXTELT_OFFSET]] to i16
+; LE128-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to half
+; LE128-NEXT:    ret half [[R]]
+;
+; BE128-LABEL: @bitcast_fp16vec_index1(
+; BE128-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
+; BE128-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to half
+; BE128-NEXT:    ret half [[R]]
 ;
   %v = bitcast i32 %x to <2 x half>
   %r = extractelement <2 x half> %v, i8 1
@@ -549,10 +583,27 @@
 }
 
 define bfloat @bitcast_bfp16vec_index0(i32 %x) {
-; ANY-LABEL: @bitcast_bfp16vec_index0(
-; ANY-NEXT:    [[V:%.*]] = bitcast i32 [[X:%.*]] to <2 x bfloat>
-; ANY-NEXT:    [[R:%.*]] = extractelement <2 x bfloat> [[V]], i64 0
-; ANY-NEXT:    ret bfloat [[R]]
+; LE64-LABEL: @bitcast_bfp16vec_index0(
+; LE64-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
+; LE64-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to bfloat
+; LE64-NEXT:    ret bfloat [[R]]
+;
+; BE64-LABEL: @bitcast_bfp16vec_index0(
+; BE64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16
+; BE64-NEXT:    [[TMP1:%.*]] = trunc i32 [[EXTELT_OFFSET]] to i16
+; BE64-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to bfloat
+; BE64-NEXT:    ret bfloat [[R]]
+;
+; LE128-LABEL: @bitcast_bfp16vec_index0(
+; LE128-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
+; LE128-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to bfloat
+; LE128-NEXT:    ret bfloat [[R]]
+;
+; BE128-LABEL: @bitcast_bfp16vec_index0(
+; BE128-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16
+; BE128-NEXT:    [[TMP1:%.*]] = trunc i32 [[EXTELT_OFFSET]] to i16
+; BE128-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to bfloat
+; BE128-NEXT:    ret bfloat [[R]]
 ;
   %v = bitcast i32 %x to <2 x bfloat>
   %r = extractelement <2 x bfloat> %v, i8 0
@@ -560,10 +611,27 @@
 }
 
 define bfloat @bitcast_bfp16vec_index1(i32 %x) {
-; ANY-LABEL: @bitcast_bfp16vec_index1(
-; ANY-NEXT:    [[V:%.*]] = bitcast i32 [[X:%.*]] to <2 x bfloat>
-; ANY-NEXT:    [[R:%.*]] = extractelement <2 x bfloat> [[V]], i64 1
-; ANY-NEXT:    ret bfloat [[R]]
+; LE64-LABEL: @bitcast_bfp16vec_index1(
+; LE64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16
+; LE64-NEXT:    [[TMP1:%.*]] = trunc i32 [[EXTELT_OFFSET]] to i16
+; LE64-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to bfloat
+; LE64-NEXT:    ret bfloat [[R]]
+;
+; BE64-LABEL: @bitcast_bfp16vec_index1(
+; BE64-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
+; BE64-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to bfloat
+; BE64-NEXT:    ret bfloat [[R]]
+;
+; LE128-LABEL: @bitcast_bfp16vec_index1(
+; LE128-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16
+; LE128-NEXT:    [[TMP1:%.*]] = trunc i32 [[EXTELT_OFFSET]] to i16
+; LE128-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to bfloat
+; LE128-NEXT:    ret bfloat [[R]]
+;
+; BE128-LABEL: @bitcast_bfp16vec_index1(
+; BE128-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
+; BE128-NEXT:    [[R:%.*]] = bitcast i16 [[TMP1]] to bfloat
+; BE128-NEXT:    ret bfloat [[R]]
 ;
   %v = bitcast i32 %x to <2 x bfloat>
   %r = extractelement <2 x bfloat> %v, i8 1
@@ -571,10 +639,21 @@
 }
 
 define float @bitcast_fp32vec_index0(i64 %x) {
-; ANY-LABEL: @bitcast_fp32vec_index0(
-; ANY-NEXT:    [[V:%.*]] = bitcast i64 [[X:%.*]] to <2 x float>
-; ANY-NEXT:    [[R:%.*]] = extractelement <2 x float> [[V]], i64 0
-; ANY-NEXT:    ret float [[R]]
+; LE64-LABEL: @bitcast_fp32vec_index0(
+; LE64-NEXT:    [[TMP1:%.*]] = trunc i64 [[X:%.*]] to i32
+; LE64-NEXT:    [[R:%.*]] = bitcast i32 [[TMP1]] to float
+; LE64-NEXT:    ret float [[R]]
+;
+; BE64-LABEL: @bitcast_fp32vec_index0(
+; BE64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i64 [[X:%.*]], 32
+; BE64-NEXT:    [[TMP1:%.*]] = trunc i64 [[EXTELT_OFFSET]] to i32
+; BE64-NEXT:    [[R:%.*]] = bitcast i32 [[TMP1]] to float
+; BE64-NEXT:    ret float [[R]]
+;
+; ANY128-LABEL: @bitcast_fp32vec_index0(
+; ANY128-NEXT:    [[V:%.*]] = bitcast i64 [[X:%.*]] to <2 x float>
+; ANY128-NEXT:    [[R:%.*]] = extractelement <2 x float> [[V]], i64 0
+; ANY128-NEXT:    ret float [[R]]
 ;
   %v = bitcast i64 %x to <2 x float>
   %r = extractelement <2 x float> %v, i8 0
@@ -582,10 +661,21 @@
 }
 
 define float @bitcast_fp32vec_index1(i64 %x) {
-; ANY-LABEL: @bitcast_fp32vec_index1(
-; ANY-NEXT:    [[V:%.*]] = bitcast i64 [[X:%.*]] to <2 x float>
-; ANY-NEXT:    [[R:%.*]] = extractelement <2 x float> [[V]], i64 1
-; ANY-NEXT:    ret float [[R]]
+; LE64-LABEL: @bitcast_fp32vec_index1(
+; LE64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i64 [[X:%.*]], 32
+; LE64-NEXT:    [[TMP1:%.*]] = trunc i64 [[EXTELT_OFFSET]] to i32
+; LE64-NEXT:    [[R:%.*]] = bitcast i32 [[TMP1]] to float
+; LE64-NEXT:    ret float [[R]]
+;
+; BE64-LABEL: @bitcast_fp32vec_index1(
+; BE64-NEXT:    [[TMP1:%.*]] = trunc i64 [[X:%.*]] to i32
+; BE64-NEXT:    [[R:%.*]] = bitcast i32 [[TMP1]] to float
+; BE64-NEXT:    ret float [[R]]
+;
+; ANY128-LABEL: @bitcast_fp32vec_index1(
+; ANY128-NEXT:    [[V:%.*]] = bitcast i64 [[X:%.*]] to <2 x float>
+; ANY128-NEXT:    [[R:%.*]] = extractelement <2 x float> [[V]], i64 1
+; ANY128-NEXT:    ret float [[R]]
 ;
   %v = bitcast i64 %x to <2 x float>
   %r = extractelement <2 x float> %v, i8 1
@@ -593,10 +683,14 @@
 }
 
 define double @bitcast_fp64vec64_index0(i64 %x) {
-; ANY-LABEL: @bitcast_fp64vec64_index0(
-; ANY-NEXT:    [[V:%.*]] = bitcast i64 [[X:%.*]] to <1 x double>
-; ANY-NEXT:    [[R:%.*]] = extractelement <1 x double> [[V]], i64 0
-; ANY-NEXT:    ret double [[R]]
+; ANY64-LABEL: @bitcast_fp64vec64_index0(
+; ANY64-NEXT:    [[R:%.*]] = bitcast i64 [[X:%.*]] to double
+; ANY64-NEXT:    ret double [[R]]
+;
+; ANY128-LABEL: @bitcast_fp64vec64_index0(
+; ANY128-NEXT:    [[V:%.*]] = bitcast i64 [[X:%.*]] to <1 x double>
+; ANY128-NEXT:    [[R:%.*]] = extractelement <1 x double> [[V]], i64 0
+; ANY128-NEXT:    ret double [[R]]
 ;
   %v = bitcast i64 %x to <1 x double>
   %r = extractelement <1 x double> %v, i8 0
@@ -604,10 +698,21 @@
 }
 
 define double @bitcast_fp64vec_index0(i128 %x) {
-; ANY-LABEL: @bitcast_fp64vec_index0(
-; ANY-NEXT:    [[V:%.*]] = bitcast i128 [[X:%.*]] to <2 x double>
-; ANY-NEXT:    [[R:%.*]] = extractelement <2 x double> [[V]], i64 0
-; ANY-NEXT:    ret double [[R]]
+; ANY64-LABEL: @bitcast_fp64vec_index0(
+; ANY64-NEXT:    [[V:%.*]] = bitcast i128 [[X:%.*]] to <2 x double>
+; ANY64-NEXT:    [[R:%.*]] = extractelement <2 x double> [[V]], i64 0
+; ANY64-NEXT:    ret double [[R]]
+;
+; LE128-LABEL: @bitcast_fp64vec_index0(
+; LE128-NEXT:    [[TMP1:%.*]] = trunc i128 [[X:%.*]] to i64
+; LE128-NEXT:    [[R:%.*]] = bitcast i64 [[TMP1]] to double
+; LE128-NEXT:    ret double [[R]]
+;
+; BE128-LABEL: @bitcast_fp64vec_index0(
+; BE128-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i128 [[X:%.*]], 64
+; BE128-NEXT:    [[TMP1:%.*]] = trunc i128 [[EXTELT_OFFSET]] to i64
+; BE128-NEXT:    [[R:%.*]] = bitcast i64 [[TMP1]] to double
+; BE128-NEXT:    ret double [[R]]
 ;
   %v = bitcast i128 %x to <2 x double>
   %r = extractelement <2 x double> %v, i8 0
@@ -615,10 +720,21 @@
 }
 
 define double @bitcast_fp64vec_index1(i128 %x) {
-; ANY-LABEL: @bitcast_fp64vec_index1(
-; ANY-NEXT:    [[V:%.*]] = bitcast i128 [[X:%.*]] to <2 x double>
-; ANY-NEXT:    [[R:%.*]] = extractelement <2 x double> [[V]], i64 1
-; ANY-NEXT:    ret double [[R]]
+; ANY64-LABEL: @bitcast_fp64vec_index1(
+; ANY64-NEXT:    [[V:%.*]] = bitcast i128 [[X:%.*]] to <2 x double>
+; ANY64-NEXT:    [[R:%.*]] = extractelement <2 x double> [[V]], i64 1
+; ANY64-NEXT:    ret double [[R]]
+;
+; LE128-LABEL: @bitcast_fp64vec_index1(
+; LE128-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i128 [[X:%.*]], 64
+; LE128-NEXT:    [[TMP1:%.*]] = trunc i128 [[EXTELT_OFFSET]] to i64
+; LE128-NEXT:    [[R:%.*]] = bitcast i64 [[TMP1]] to double
+; LE128-NEXT:    ret double [[R]]
+;
+; BE128-LABEL: @bitcast_fp64vec_index1(
+; BE128-NEXT:    [[TMP1:%.*]] = trunc i128 [[X:%.*]] to i64
+; BE128-NEXT:    [[R:%.*]] = bitcast i64 [[TMP1]] to double
+; BE128-NEXT:    ret double [[R]]
 ;
   %v = bitcast i128 %x to <2 x double>
   %r = extractelement <2 x double> %v, i8 1
@@ -744,11 +860,24 @@
 }
 
 define i1 @bit_extract_cmp(i64 %x) {
-; ANY-LABEL: @bit_extract_cmp(
-; ANY-NEXT:    [[V:%.*]] = bitcast i64 [[X:%.*]] to <2 x float>
-; ANY-NEXT:    [[E:%.*]] = extractelement <2 x float> [[V]], i64 1
-; ANY-NEXT:    [[R:%.*]] = fcmp oeq float [[E]], 0.000000e+00
-; ANY-NEXT:    ret i1 [[R]]
+; LE64-LABEL: @bit_extract_cmp(
+; LE64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i64 [[X:%.*]], 32
+; LE64-NEXT:    [[TMP1:%.*]] = trunc i64 [[EXTELT_OFFSET]] to i32
+; LE64-NEXT:    [[E:%.*]] = bitcast i32 [[TMP1]] to float
+; LE64-NEXT:    [[R:%.*]] = fcmp oeq float [[E]], 0.000000e+00
+; LE64-NEXT:    ret i1 [[R]]
+;
+; BE64-LABEL: @bit_extract_cmp(
+; BE64-NEXT:    [[TMP1:%.*]] = trunc i64 [[X:%.*]] to i32
+; BE64-NEXT:    [[E:%.*]] = bitcast i32 [[TMP1]] to float
+; BE64-NEXT:    [[R:%.*]] = fcmp oeq float [[E]], 0.000000e+00
+; BE64-NEXT:    ret i1 [[R]]
+;
+; ANY128-LABEL: @bit_extract_cmp(
+; ANY128-NEXT:    [[V:%.*]] = bitcast i64 [[X:%.*]] to <2 x float>
+; ANY128-NEXT:    [[E:%.*]] = extractelement <2 x float> [[V]], i64 1
+; ANY128-NEXT:    [[R:%.*]] = fcmp oeq float [[E]], 0.000000e+00
+; ANY128-NEXT:    ret i1 [[R]]
 ;
   %v = bitcast i64 %x to <2 x float>
   %e = extractelement <2 x float> %v, i8 1