forked from OSchip/llvm-project
InstCombine: Scalarize single use icmp/fcmp
llvm-svn: 348801
This commit is contained in:
parent
5c00519c9a
commit
9ccde61f81
|
@ -48,6 +48,8 @@ using namespace PatternMatch;
|
|||
/// Return true if the value is cheaper to scalarize than it is to leave as a
|
||||
/// vector operation. isConstant indicates whether we're extracting one known
|
||||
/// element. If false we're extracting a variable index.
|
||||
//
|
||||
// FIXME: It's possible to create more instructions that previously existed.
|
||||
static bool cheapToScalarize(Value *V, bool isConstant) {
|
||||
if (Constant *C = dyn_cast<Constant>(V)) {
|
||||
if (isConstant) return true;
|
||||
|
@ -310,6 +312,16 @@ Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) {
|
|||
return BinaryOperator::CreateWithCopiedFlags(BO->getOpcode(), E0, E1, BO);
|
||||
}
|
||||
|
||||
Value *X, *Y;
|
||||
CmpInst::Predicate Pred;
|
||||
if (match(SrcVec, m_Cmp(Pred, m_Value(X), m_Value(Y))) &&
|
||||
cheapToScalarize(SrcVec, IndexC)) {
|
||||
// extelt (cmp X, Y), Index --> cmp (extelt X, Index), (extelt Y, Index)
|
||||
Value *E0 = Builder.CreateExtractElement(X, Index);
|
||||
Value *E1 = Builder.CreateExtractElement(Y, Index);
|
||||
return CmpInst::Create(cast<CmpInst>(SrcVec)->getOpcode(), Pred, E0, E1);
|
||||
}
|
||||
|
||||
if (auto *I = dyn_cast<Instruction>(SrcVec)) {
|
||||
if (auto *IE = dyn_cast<InsertElementInst>(I)) {
|
||||
// Extracting the inserted element?
|
||||
|
|
|
@ -137,10 +137,10 @@ define float @extract_element_constant_vector_variable_index(i32 %y) {
|
|||
|
||||
define i1 @cheap_to_extract_icmp(<4 x i32> %x, <4 x i1> %y) {
|
||||
; CHECK-LABEL: @cheap_to_extract_icmp(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> [[X:%.*]], zeroinitializer
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x i1> [[CMP]], i32 2
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x i1> [[Y:%.*]], i32 2
|
||||
; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP1]], [[TMP2]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x i32> [[X:%.*]], i32 2
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x i1> [[Y:%.*]], i32 2
|
||||
; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP2]], [[TMP3]]
|
||||
; CHECK-NEXT: ret i1 [[R]]
|
||||
;
|
||||
%cmp = icmp eq <4 x i32> %x, zeroinitializer
|
||||
|
@ -151,10 +151,10 @@ define i1 @cheap_to_extract_icmp(<4 x i32> %x, <4 x i1> %y) {
|
|||
|
||||
define i1 @cheap_to_extract_fcmp(<4 x float> %x, <4 x i1> %y) {
|
||||
; CHECK-LABEL: @cheap_to_extract_fcmp(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq <4 x float> [[X:%.*]], zeroinitializer
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x i1> [[CMP]], i32 2
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x i1> [[Y:%.*]], i32 2
|
||||
; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP1]], [[TMP2]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x float> [[X:%.*]], i32 2
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = fcmp oeq float [[TMP1]], 0.000000e+00
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x i1> [[Y:%.*]], i32 2
|
||||
; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP2]], [[TMP3]]
|
||||
; CHECK-NEXT: ret i1 [[R]]
|
||||
;
|
||||
%cmp = fcmp oeq <4 x float> %x, zeroinitializer
|
||||
|
@ -165,8 +165,8 @@ define i1 @cheap_to_extract_fcmp(<4 x float> %x, <4 x i1> %y) {
|
|||
|
||||
define i1 @extractelt_vector_icmp_constrhs(<2 x i32> %arg) {
|
||||
; CHECK-LABEL: @extractelt_vector_icmp_constrhs(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[ARG:%.*]], zeroinitializer
|
||||
; CHECK-NEXT: [[EXT:%.*]] = extractelement <2 x i1> [[CMP]], i32 0
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = extractelement <2 x i32> [[ARG:%.*]], i32 0
|
||||
; CHECK-NEXT: [[EXT:%.*]] = icmp eq i32 [[TMP1]], 0
|
||||
; CHECK-NEXT: ret i1 [[EXT]]
|
||||
;
|
||||
%cmp = icmp eq <2 x i32> %arg, zeroinitializer
|
||||
|
@ -176,8 +176,8 @@ define i1 @extractelt_vector_icmp_constrhs(<2 x i32> %arg) {
|
|||
|
||||
define i1 @extractelt_vector_fcmp_constrhs(<2 x float> %arg) {
|
||||
; CHECK-LABEL: @extractelt_vector_fcmp_constrhs(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq <2 x float> [[ARG:%.*]], zeroinitializer
|
||||
; CHECK-NEXT: [[EXT:%.*]] = extractelement <2 x i1> [[CMP]], i32 0
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = extractelement <2 x float> [[ARG:%.*]], i32 0
|
||||
; CHECK-NEXT: [[EXT:%.*]] = fcmp oeq float [[TMP1]], 0.000000e+00
|
||||
; CHECK-NEXT: ret i1 [[EXT]]
|
||||
;
|
||||
%cmp = fcmp oeq <2 x float> %arg, zeroinitializer
|
||||
|
@ -187,8 +187,8 @@ define i1 @extractelt_vector_fcmp_constrhs(<2 x float> %arg) {
|
|||
|
||||
define i1 @extractelt_vector_icmp_constrhs_dynidx(<2 x i32> %arg, i32 %idx) {
|
||||
; CHECK-LABEL: @extractelt_vector_icmp_constrhs_dynidx(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[ARG:%.*]], zeroinitializer
|
||||
; CHECK-NEXT: [[EXT:%.*]] = extractelement <2 x i1> [[CMP]], i32 [[IDX:%.*]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = extractelement <2 x i32> [[ARG:%.*]], i32 [[IDX:%.*]]
|
||||
; CHECK-NEXT: [[EXT:%.*]] = icmp eq i32 [[TMP1]], 0
|
||||
; CHECK-NEXT: ret i1 [[EXT]]
|
||||
;
|
||||
%cmp = icmp eq <2 x i32> %arg, zeroinitializer
|
||||
|
@ -198,8 +198,8 @@ define i1 @extractelt_vector_icmp_constrhs_dynidx(<2 x i32> %arg, i32 %idx) {
|
|||
|
||||
define i1 @extractelt_vector_fcmp_constrhs_dynidx(<2 x float> %arg, i32 %idx) {
|
||||
; CHECK-LABEL: @extractelt_vector_fcmp_constrhs_dynidx(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq <2 x float> [[ARG:%.*]], zeroinitializer
|
||||
; CHECK-NEXT: [[EXT:%.*]] = extractelement <2 x i1> [[CMP]], i32 [[IDX:%.*]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = extractelement <2 x float> [[ARG:%.*]], i32 [[IDX:%.*]]
|
||||
; CHECK-NEXT: [[EXT:%.*]] = fcmp oeq float [[TMP1]], 0.000000e+00
|
||||
; CHECK-NEXT: ret i1 [[EXT]]
|
||||
;
|
||||
%cmp = fcmp oeq <2 x float> %arg, zeroinitializer
|
||||
|
|
Loading…
Reference in New Issue