[llvm] df525c7 - [InstCombine] fold fake floating point vector extract to shift+trunc.
via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 29 19:12:49 PDT 2022
Author: jacquesguan
Date: 2022-08-30T10:12:16+08:00
New Revision: df525c7705d8f57b660bac18c9dd800a64b1917e
URL: https://github.com/llvm/llvm-project/commit/df525c7705d8f57b660bac18c9dd800a64b1917e
DIFF: https://github.com/llvm/llvm-project/commit/df525c7705d8f57b660bac18c9dd800a64b1917e.diff
LOG: [InstCombine] fold fake floating point vector extract to shift+trunc.
This patch supports the FP part of D111082.
Differential Revision: https://reviews.llvm.org/D125750
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
llvm/test/Transforms/InstCombine/extractelement.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index 4467a4f8a2668..9a144de36af32 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -191,8 +191,7 @@ Instruction *InstCombinerImpl::foldBitcastExtElt(ExtractElementInst &Ext) {
// 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 @@ Instruction *InstCombinerImpl::foldBitcastExtElt(ExtractElementInst &Ext) {
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
index 439df71e85105..e045804e17f74 100644
--- a/llvm/test/Transforms/InstCombine/extractelement.ll
+++ b/llvm/test/Transforms/InstCombine/extractelement.ll
@@ -436,10 +436,16 @@ define i8 @bitcast_fp_index0(float %x) {
}
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]]
+; ANYLE-LABEL: @bitcast_fp16vec_index0(
+; ANYLE-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
+; ANYLE-NEXT: [[R:%.*]] = bitcast i16 [[TMP1]] to half
+; ANYLE-NEXT: ret half [[R]]
+;
+; ANYBE-LABEL: @bitcast_fp16vec_index0(
+; ANYBE-NEXT: [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16
+; ANYBE-NEXT: [[TMP1:%.*]] = trunc i32 [[EXTELT_OFFSET]] to i16
+; ANYBE-NEXT: [[R:%.*]] = bitcast i16 [[TMP1]] to half
+; ANYBE-NEXT: ret half [[R]]
;
%v = bitcast i32 %x to <2 x half>
%r = extractelement <2 x half> %v, i8 0
@@ -447,10 +453,16 @@ define half @bitcast_fp16vec_index0(i32 %x) {
}
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]]
+; ANYLE-LABEL: @bitcast_fp16vec_index1(
+; ANYLE-NEXT: [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16
+; ANYLE-NEXT: [[TMP1:%.*]] = trunc i32 [[EXTELT_OFFSET]] to i16
+; ANYLE-NEXT: [[R:%.*]] = bitcast i16 [[TMP1]] to half
+; ANYLE-NEXT: ret half [[R]]
+;
+; ANYBE-LABEL: @bitcast_fp16vec_index1(
+; ANYBE-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
+; ANYBE-NEXT: [[R:%.*]] = bitcast i16 [[TMP1]] to half
+; ANYBE-NEXT: ret half [[R]]
;
%v = bitcast i32 %x to <2 x half>
%r = extractelement <2 x half> %v, i8 1
@@ -458,10 +470,16 @@ define half @bitcast_fp16vec_index1(i32 %x) {
}
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]]
+; ANYLE-LABEL: @bitcast_bfp16vec_index0(
+; ANYLE-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
+; ANYLE-NEXT: [[R:%.*]] = bitcast i16 [[TMP1]] to bfloat
+; ANYLE-NEXT: ret bfloat [[R]]
+;
+; ANYBE-LABEL: @bitcast_bfp16vec_index0(
+; ANYBE-NEXT: [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16
+; ANYBE-NEXT: [[TMP1:%.*]] = trunc i32 [[EXTELT_OFFSET]] to i16
+; ANYBE-NEXT: [[R:%.*]] = bitcast i16 [[TMP1]] to bfloat
+; ANYBE-NEXT: ret bfloat [[R]]
;
%v = bitcast i32 %x to <2 x bfloat>
%r = extractelement <2 x bfloat> %v, i8 0
@@ -469,10 +487,16 @@ define bfloat @bitcast_bfp16vec_index0(i32 %x) {
}
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]]
+; ANYLE-LABEL: @bitcast_bfp16vec_index1(
+; ANYLE-NEXT: [[EXTELT_OFFSET:%.*]] = lshr i32 [[X:%.*]], 16
+; ANYLE-NEXT: [[TMP1:%.*]] = trunc i32 [[EXTELT_OFFSET]] to i16
+; ANYLE-NEXT: [[R:%.*]] = bitcast i16 [[TMP1]] to bfloat
+; ANYLE-NEXT: ret bfloat [[R]]
+;
+; ANYBE-LABEL: @bitcast_bfp16vec_index1(
+; ANYBE-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
+; ANYBE-NEXT: [[R:%.*]] = bitcast i16 [[TMP1]] to bfloat
+; ANYBE-NEXT: ret bfloat [[R]]
;
%v = bitcast i32 %x to <2 x bfloat>
%r = extractelement <2 x bfloat> %v, i8 1
@@ -480,10 +504,26 @@ define bfloat @bitcast_bfp16vec_index1(i32 %x) {
}
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]]
+;
+; LE128-LABEL: @bitcast_fp32vec_index0(
+; LE128-NEXT: [[V:%.*]] = bitcast i64 [[X:%.*]] to <2 x float>
+; LE128-NEXT: [[R:%.*]] = extractelement <2 x float> [[V]], i64 0
+; LE128-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]]
+;
+; BE128-LABEL: @bitcast_fp32vec_index0(
+; BE128-NEXT: [[V:%.*]] = bitcast i64 [[X:%.*]] to <2 x float>
+; BE128-NEXT: [[R:%.*]] = extractelement <2 x float> [[V]], i64 0
+; BE128-NEXT: ret float [[R]]
;
%v = bitcast i64 %x to <2 x float>
%r = extractelement <2 x float> %v, i8 0
@@ -491,10 +531,26 @@ define float @bitcast_fp32vec_index0(i64 %x) {
}
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]]
+;
+; LE128-LABEL: @bitcast_fp32vec_index1(
+; LE128-NEXT: [[V:%.*]] = bitcast i64 [[X:%.*]] to <2 x float>
+; LE128-NEXT: [[R:%.*]] = extractelement <2 x float> [[V]], i64 1
+; LE128-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]]
+;
+; BE128-LABEL: @bitcast_fp32vec_index1(
+; BE128-NEXT: [[V:%.*]] = bitcast i64 [[X:%.*]] to <2 x float>
+; BE128-NEXT: [[R:%.*]] = extractelement <2 x float> [[V]], i64 1
+; BE128-NEXT: ret float [[R]]
;
%v = bitcast i64 %x to <2 x float>
%r = extractelement <2 x float> %v, i8 1
@@ -502,10 +558,23 @@ define float @bitcast_fp32vec_index1(i64 %x) {
}
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]]
+; LE64-LABEL: @bitcast_fp64vec64_index0(
+; LE64-NEXT: [[R:%.*]] = bitcast i64 [[X:%.*]] to double
+; LE64-NEXT: ret double [[R]]
+;
+; LE128-LABEL: @bitcast_fp64vec64_index0(
+; LE128-NEXT: [[V:%.*]] = bitcast i64 [[X:%.*]] to <1 x double>
+; LE128-NEXT: [[R:%.*]] = extractelement <1 x double> [[V]], i64 0
+; LE128-NEXT: ret double [[R]]
+;
+; BE64-LABEL: @bitcast_fp64vec64_index0(
+; BE64-NEXT: [[R:%.*]] = bitcast i64 [[X:%.*]] to double
+; BE64-NEXT: ret double [[R]]
+;
+; BE128-LABEL: @bitcast_fp64vec64_index0(
+; BE128-NEXT: [[V:%.*]] = bitcast i64 [[X:%.*]] to <1 x double>
+; BE128-NEXT: [[R:%.*]] = extractelement <1 x double> [[V]], i64 0
+; BE128-NEXT: ret double [[R]]
;
%v = bitcast i64 %x to <1 x double>
%r = extractelement <1 x double> %v, i8 0
@@ -513,10 +582,26 @@ define double @bitcast_fp64vec64_index0(i64 %x) {
}
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]]
+; LE64-LABEL: @bitcast_fp64vec_index0(
+; LE64-NEXT: [[V:%.*]] = bitcast i128 [[X:%.*]] to <2 x double>
+; LE64-NEXT: [[R:%.*]] = extractelement <2 x double> [[V]], i64 0
+; LE64-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]]
+;
+; BE64-LABEL: @bitcast_fp64vec_index0(
+; BE64-NEXT: [[V:%.*]] = bitcast i128 [[X:%.*]] to <2 x double>
+; BE64-NEXT: [[R:%.*]] = extractelement <2 x double> [[V]], i64 0
+; BE64-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
@@ -524,10 +609,26 @@ define double @bitcast_fp64vec_index0(i128 %x) {
}
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]]
+; LE64-LABEL: @bitcast_fp64vec_index1(
+; LE64-NEXT: [[V:%.*]] = bitcast i128 [[X:%.*]] to <2 x double>
+; LE64-NEXT: [[R:%.*]] = extractelement <2 x double> [[V]], i64 1
+; LE64-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]]
+;
+; BE64-LABEL: @bitcast_fp64vec_index1(
+; BE64-NEXT: [[V:%.*]] = bitcast i128 [[X:%.*]] to <2 x double>
+; BE64-NEXT: [[R:%.*]] = extractelement <2 x double> [[V]], i64 1
+; BE64-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
@@ -654,11 +755,27 @@ define i8 @bitcast_scalar_index0_use(i64 %x) {
}
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: [[TMP1:%.*]] = and i64 [[X:%.*]], 9223372032559808512
+; LE64-NEXT: [[R:%.*]] = icmp eq i64 [[TMP1]], 0
+; LE64-NEXT: ret i1 [[R]]
+;
+; LE128-LABEL: @bit_extract_cmp(
+; LE128-NEXT: [[V:%.*]] = bitcast i64 [[X:%.*]] to <2 x float>
+; LE128-NEXT: [[E:%.*]] = extractelement <2 x float> [[V]], i64 1
+; LE128-NEXT: [[R:%.*]] = fcmp oeq float [[E]], 0.000000e+00
+; LE128-NEXT: ret i1 [[R]]
+;
+; BE64-LABEL: @bit_extract_cmp(
+; BE64-NEXT: [[TMP1:%.*]] = and i64 [[X:%.*]], 2147483647
+; BE64-NEXT: [[R:%.*]] = icmp eq i64 [[TMP1]], 0
+; BE64-NEXT: ret i1 [[R]]
+;
+; BE128-LABEL: @bit_extract_cmp(
+; BE128-NEXT: [[V:%.*]] = bitcast i64 [[X:%.*]] to <2 x float>
+; BE128-NEXT: [[E:%.*]] = extractelement <2 x float> [[V]], i64 1
+; BE128-NEXT: [[R:%.*]] = fcmp oeq float [[E]], 0.000000e+00
+; BE128-NEXT: ret i1 [[R]]
;
%v = bitcast i64 %x to <2 x float>
%e = extractelement <2 x float> %v, i8 1
More information about the llvm-commits
mailing list