case ISD::BUILD_PAIR: R = SoftenFloatRes_BUILD_PAIR(N); break;
case ISD::ConstantFP: R = SoftenFloatRes_ConstantFP(N, ResNo); break;
case ISD::EXTRACT_VECTOR_ELT:
- R = SoftenFloatRes_EXTRACT_VECTOR_ELT(N); break;
+ R = SoftenFloatRes_EXTRACT_VECTOR_ELT(N, ResNo); break;
case ISD::FABS: R = SoftenFloatRes_FABS(N, ResNo); break;
case ISD::FMINNUM: R = SoftenFloatRes_FMINNUM(N); break;
case ISD::FMAXNUM: R = SoftenFloatRes_FMAXNUM(N); break;
}
}
-SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_VECTOR_ELT(SDNode *N) {
+SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_VECTOR_ELT(SDNode *N, unsigned ResNo) {
+ // When LegalInHWReg, keep the extracted value in register.
+ if (isLegalInHWReg(N->getValueType(ResNo)))
+ return SDValue(N, ResNo);
SDValue NewOp = BitConvertVectorToIntegerVector(N->getOperand(0));
return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N),
NewOp.getValueType().getVectorElementType(),
SDValue SoftenFloatRes_BITCAST(SDNode *N, unsigned ResNo);
SDValue SoftenFloatRes_BUILD_PAIR(SDNode *N);
SDValue SoftenFloatRes_ConstantFP(SDNode *N, unsigned ResNo);
- SDValue SoftenFloatRes_EXTRACT_VECTOR_ELT(SDNode *N);
+ SDValue SoftenFloatRes_EXTRACT_VECTOR_ELT(SDNode *N, unsigned ResNo);
SDValue SoftenFloatRes_FABS(SDNode *N, unsigned ResNo);
SDValue SoftenFloatRes_FMINNUM(SDNode *N);
SDValue SoftenFloatRes_FMAXNUM(SDNode *N);
; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+sse4.1 | FileCheck %s --check-prefix=X64 --check-prefix=SSE-X64 --check-prefix=SSE41-X64
; RUN: llc < %s -mtriple=i686-unknown -mattr=+avx | FileCheck %s --check-prefix=X32 --check-prefix=AVX-X32
; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx | FileCheck %s --check-prefix=X64 --check-prefix=AVX-X64
+; RUN: llc < %s -O2 -mtriple=x86_64-linux-android -mattr=+mmx -enable-legalize-types-checking \
+; RUN: | FileCheck %s --check-prefix=X64 --check-prefix=SSE-X64 --check-prefix=SSE-F128
+; RUN: llc < %s -O2 -mtriple=x86_64-linux-gnu -mattr=+mmx -enable-legalize-types-checking \
+; RUN: | FileCheck %s --check-prefix=X64 --check-prefix=SSE-X64 --check-prefix=SSE-F128
define void @extract_i8_0(i8* nocapture %dst, <16 x i8> %foo) nounwind {
; SSE2-X32-LABEL: extract_i8_0:
ret void
}
+define void @extract_f128_0(fp128* nocapture %dst, <2 x fp128> %foo) nounwind {
+; SSE-F128-LABEL: extract_f128_0:
+; SSE-F128: # BB#0:
+; SSE-F128-NEXT: movaps %xmm0, (%rdi)
+; SSE-F128-NEXT: retq
+ %vecext = extractelement <2 x fp128> %foo, i32 0
+ store fp128 %vecext, fp128* %dst, align 1
+ ret void
+}
+
+define void @extract_f128_1(fp128* nocapture %dst, <2 x fp128> %foo) nounwind {
+; SSE-F128-LABEL: extract_f128_1:
+; SSE-F128: # BB#0:
+; SSE-F128-NEXT: movaps %xmm1, (%rdi)
+; SSE-F128-NEXT: retq
+ %vecext = extractelement <2 x fp128> %foo, i32 1
+ store fp128 %vecext, fp128* %dst, align 1
+ ret void
+}
+
define void @extract_i8_undef(i8* nocapture %dst, <16 x i8> %foo) nounwind {
; X32-LABEL: extract_i8_undef:
; X32: # BB#0:
store double %vecext, double* %dst, align 1
ret void
}
+
+define void @extract_f128_undef(fp128* nocapture %dst, <2 x fp128> %foo) nounwind {
+; X32-LABEL: extract_f128_undef:
+; X32: # BB#0:
+; X32-NEXT: retl
+;
+; X64-LABEL: extract_f128_undef:
+; X64: # BB#0:
+; X64-NEXT: retq
+ %vecext = extractelement <2 x fp128> %foo, i32 2 ; undef
+ store fp128 %vecext, fp128* %dst, align 1
+ ret void
+}
--- /dev/null
+; RUN: llc < %s -O2 -mtriple=x86_64-linux-android -mattr=+mmx \
+; RUN: -enable-legalize-types-checking | FileCheck %s
+; RUN: llc < %s -O2 -mtriple=x86_64-linux-gnu -mattr=+mmx \
+; RUN: -enable-legalize-types-checking | FileCheck %s
+
+; Test the softened result of extractelement op code.
+define fp128 @TestExtract(<2 x double> %x) {
+entry:
+ ; Simplified instruction pattern from the output of llvm before r289042,
+ ; for a boost function ...::insert<...>::traverse<...>().
+ %a = fpext <2 x double> %x to <2 x fp128>
+ %0 = extractelement <2 x fp128> %a, i32 0
+ %1 = extractelement <2 x fp128> %a, i32 1
+ %2 = fmul fp128 %0, %1
+ ret fp128 %2
+; CHECK-LABEL: TestExtract:
+; CHECK: movaps %xmm0, (%rsp)
+; CHECK: callq __extenddftf2
+; CHECK: callq __extenddftf2
+; CHECK: callq __multf3
+; CHECK: retq
+}