Index: include/llvm/CodeGen/BasicTTIImpl.h =================================================================== --- include/llvm/CodeGen/BasicTTIImpl.h +++ include/llvm/CodeGen/BasicTTIImpl.h @@ -1139,7 +1139,8 @@ SmallVector CustomCost; for (unsigned ISD : ISDs) { if (TLI->isOperationLegalOrPromote(ISD, LT.second)) { - if (IID == Intrinsic::fabs && TLI->isFAbsFree(LT.second)) { + if (IID == Intrinsic::fabs && LT.second.isFloatingPoint() && + TLI->isFAbsFree(LT.second)) { return 0; } Index: test/Transforms/SLPVectorizer/X86/software-float.ll =================================================================== --- /dev/null +++ test/Transforms/SLPVectorizer/X86/software-float.ll @@ -0,0 +1,60 @@ +; Regression test from https://bugs.llvm.org/show_bug.cgi?id=39168 +; Based on code from `compiler-rt/lib/builtins/multc3.c` +; On plaforms where fp128 lowers to an interger type (soft-fp) we +; shouldn't be calling isFAbsFree() on the legalized type. + +; RUN: opt -slp-vectorizer -S %s + +target triple = "i686-unknown-linux-gnu" + +; Function Attrs: nounwind readnone uwtable +define dso_local fp128 @__multc3(fp128 %a, fp128 %b, fp128 %c, fp128 %d) local_unnamed_addr #0 { +entry: + %0 = tail call fp128 @llvm.fabs.f128(fp128 %a) #2 + %cmpinf = fcmp oeq fp128 %0, 0xL00000000000000007FFF000000000000 + %1 = tail call fp128 @llvm.fabs.f128(fp128 %b) #2 + %cmpinf1 = fcmp oeq fp128 %1, 0xL00000000000000007FFF000000000000 + %or.cond = or i1 %cmpinf, %cmpinf1 + br i1 %or.cond, label %if.then, label %if.end + +if.then: ; preds = %entry + %conv = uitofp i1 %cmpinf to x86_fp80 + %conv3 = fptrunc fp128 %a to x86_fp80 + %2 = tail call x86_fp80 @llvm.copysign.f80(x86_fp80 %conv, x86_fp80 %conv3) + %conv4 = fpext x86_fp80 %2 to fp128 + %conv7 = uitofp i1 %cmpinf1 to x86_fp80 + %conv8 = fptrunc fp128 %b to x86_fp80 + %3 = tail call x86_fp80 @llvm.copysign.f80(x86_fp80 %conv7, x86_fp80 %conv8) + %conv9 = fpext x86_fp80 %3 to fp128 + br label %if.end + +if.end: ; preds = %entry, %if.then + %a.addr.0 = phi fp128 [ %conv4, %if.then ], [ %a, %entry ] + %b.addr.0 = phi fp128 [ %conv9, %if.then ], [ %b, %entry ] + %4 = tail call fp128 @llvm.fabs.f128(fp128 %c) #2 + %cmpinf10 = fcmp oeq fp128 %4, 0xL00000000000000007FFF000000000000 + %5 = tail call fp128 @llvm.fabs.f128(fp128 %d) #2 + %cmpinf12 = fcmp oeq fp128 %5, 0xL00000000000000007FFF000000000000 + %or.cond39 = or i1 %cmpinf10, %cmpinf12 + br i1 %or.cond39, label %if.then13, label %if.end24 + +if.then13: ; preds = %if.end + %conv16 = uitofp i1 %cmpinf10 to x86_fp80 + %conv17 = fptrunc fp128 %c to x86_fp80 + %6 = tail call x86_fp80 @llvm.copysign.f80(x86_fp80 %conv16, x86_fp80 %conv17) + %conv18 = fpext x86_fp80 %6 to fp128 + br label %if.end24 + +if.end24: ; preds = %if.end, %if.then13 + %c.addr.0 = phi fp128 [ %conv18, %if.then13 ], [ %c, %if.end ] + %add = fadd fp128 %a.addr.0, %b.addr.0 + %add25 = fadd fp128 %b.addr.0, %add + %add26 = fadd fp128 %add25, %c.addr.0 + ret fp128 %add26 +} + +declare fp128 @llvm.fabs.f128(fp128) + +declare x86_fp80 @llvm.copysign.f80(x86_fp80, x86_fp80) + +attributes #0 = { "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" }