Skip to content

Commit

Permalink
[SVE][InstCombine] Don't convert calls to fp binop intrinsics to inst…
Browse files Browse the repository at this point in the history
…ructions when strictfp is required.

There's no support to lower scalable vector constrained operations for SVE
and thus without this change we'll crash during code generation.

Differential Revision: https://reviews.llvm.org/D147600
  • Loading branch information
paulwalker-arm committed Apr 6, 2023
1 parent 5f2145a commit 65031c1
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 14 deletions.
4 changes: 4 additions & 0 deletions llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1178,6 +1178,10 @@ static Instruction::BinaryOps intrinsicIDToBinOpCode(unsigned Intrinsic) {

static std::optional<Instruction *>
instCombineSVEVectorBinOp(InstCombiner &IC, IntrinsicInst &II) {
// Bail due to missing support for ISD::STRICT_ scalable vector operations.
if (II.isStrictFP())
return std::nullopt;

auto *OpPredicate = II.getOperand(0);
auto BinOpCode = intrinsicIDToBinOpCode(II.getIntrinsicID());
if (BinOpCode == Instruction::BinaryOpsEnd ||
Expand Down
33 changes: 19 additions & 14 deletions llvm/test/Transforms/InstCombine/AArch64/sve-intrinsic-strictfp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ target triple = "aarch64-unknown-linux-gnu"
define <vscale x 2 x double> @replace_fadd_intrinsic_double_strictfp(<vscale x 2 x double> %a, <vscale x 2 x double> %b) #0 {
; CHECK: Function Attrs: strictfp
; CHECK-LABEL: @replace_fadd_intrinsic_double_strictfp(
; CHECK-NEXT: [[TMP1:%.*]] = fadd <vscale x 2 x double> [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: ret <vscale x 2 x double> [[TMP1]]
; CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i1> @llvm.aarch64.sve.ptrue.nxv2i1(i32 31) #[[ATTR2:[0-9]+]]
; CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x double> @llvm.aarch64.sve.fadd.nxv2f64(<vscale x 2 x i1> [[TMP1]], <vscale x 2 x double> [[A:%.*]], <vscale x 2 x double> [[B:%.*]]) #[[ATTR2]]
; CHECK-NEXT: ret <vscale x 2 x double> [[TMP2]]
;
%1 = tail call <vscale x 2 x i1> @llvm.aarch64.sve.ptrue.nxv2i1(i32 31) #1
%2 = tail call <vscale x 2 x double> @llvm.aarch64.sve.fadd.nxv2f64(<vscale x 2 x i1> %1, <vscale x 2 x double> %a, <vscale x 2 x double> %b) #1
Expand All @@ -21,8 +22,9 @@ define <vscale x 2 x double> @replace_fadd_intrinsic_double_strictfp(<vscale x 2
define <vscale x 2 x double> @call_replace_fadd_intrinsic_double_strictfp(<vscale x 2 x double> %a, <vscale x 2 x double> %b) #0 {
; CHECK: Function Attrs: strictfp
; CHECK-LABEL: @call_replace_fadd_intrinsic_double_strictfp(
; CHECK-NEXT: [[DOTSTRICT:%.*]] = call <vscale x 2 x double> @llvm.experimental.constrained.fadd.nxv2f64(<vscale x 2 x double> [[A:%.*]], <vscale x 2 x double> [[B:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR3:[0-9]+]]
; CHECK-NEXT: ret <vscale x 2 x double> [[DOTSTRICT]]
; CHECK-NEXT: [[TMP1:%.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.ptrue.nxv2i1(i32 31) #[[ATTR2]]
; CHECK-NEXT: [[TMP2:%.*]] = call <vscale x 2 x double> @llvm.aarch64.sve.fadd.nxv2f64(<vscale x 2 x i1> [[TMP1]], <vscale x 2 x double> [[A:%.*]], <vscale x 2 x double> [[B:%.*]]) #[[ATTR2]]
; CHECK-NEXT: ret <vscale x 2 x double> [[TMP2]]
;
%1 = call <vscale x 2 x double> @replace_fadd_intrinsic_double_strictfp(<vscale x 2 x double> %a, <vscale x 2 x double> %b) #1
ret <vscale x 2 x double> %1
Expand All @@ -33,8 +35,9 @@ define <vscale x 2 x double> @call_replace_fadd_intrinsic_double_strictfp(<vscal
define <vscale x 2 x double> @replace_fmul_intrinsic_double_strictfp(<vscale x 2 x double> %a, <vscale x 2 x double> %b) #0 {
; CHECK: Function Attrs: strictfp
; CHECK-LABEL: @replace_fmul_intrinsic_double_strictfp(
; CHECK-NEXT: [[TMP1:%.*]] = fmul <vscale x 2 x double> [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: ret <vscale x 2 x double> [[TMP1]]
; CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i1> @llvm.aarch64.sve.ptrue.nxv2i1(i32 31) #[[ATTR2]]
; CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x double> @llvm.aarch64.sve.fmul.nxv2f64(<vscale x 2 x i1> [[TMP1]], <vscale x 2 x double> [[A:%.*]], <vscale x 2 x double> [[B:%.*]]) #[[ATTR2]]
; CHECK-NEXT: ret <vscale x 2 x double> [[TMP2]]
;
%1 = tail call <vscale x 2 x i1> @llvm.aarch64.sve.ptrue.nxv2i1(i32 31) #1
%2 = tail call <vscale x 2 x double> @llvm.aarch64.sve.fmul.nxv2f64(<vscale x 2 x i1> %1, <vscale x 2 x double> %a, <vscale x 2 x double> %b) #1
Expand All @@ -46,8 +49,9 @@ define <vscale x 2 x double> @replace_fmul_intrinsic_double_strictfp(<vscale x 2
define <vscale x 2 x double> @call_replace_fmul_intrinsic_double_strictfp(<vscale x 2 x double> %a, <vscale x 2 x double> %b) #0 {
; CHECK: Function Attrs: strictfp
; CHECK-LABEL: @call_replace_fmul_intrinsic_double_strictfp(
; CHECK-NEXT: [[DOTSTRICT:%.*]] = call <vscale x 2 x double> @llvm.experimental.constrained.fmul.nxv2f64(<vscale x 2 x double> [[A:%.*]], <vscale x 2 x double> [[B:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR3]]
; CHECK-NEXT: ret <vscale x 2 x double> [[DOTSTRICT]]
; CHECK-NEXT: [[TMP1:%.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.ptrue.nxv2i1(i32 31) #[[ATTR2]]
; CHECK-NEXT: [[TMP2:%.*]] = call <vscale x 2 x double> @llvm.aarch64.sve.fmul.nxv2f64(<vscale x 2 x i1> [[TMP1]], <vscale x 2 x double> [[A:%.*]], <vscale x 2 x double> [[B:%.*]]) #[[ATTR2]]
; CHECK-NEXT: ret <vscale x 2 x double> [[TMP2]]
;
%1 = call <vscale x 2 x double> @replace_fmul_intrinsic_double_strictfp(<vscale x 2 x double> %a, <vscale x 2 x double> %b) #1
ret <vscale x 2 x double> %1
Expand All @@ -58,8 +62,9 @@ define <vscale x 2 x double> @call_replace_fmul_intrinsic_double_strictfp(<vscal
define <vscale x 2 x double> @replace_fsub_intrinsic_double_strictfp(<vscale x 2 x double> %a, <vscale x 2 x double> %b) #0 {
; CHECK: Function Attrs: strictfp
; CHECK-LABEL: @replace_fsub_intrinsic_double_strictfp(
; CHECK-NEXT: [[TMP1:%.*]] = fsub <vscale x 2 x double> [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: ret <vscale x 2 x double> [[TMP1]]
; CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i1> @llvm.aarch64.sve.ptrue.nxv2i1(i32 31) #[[ATTR2]]
; CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x double> @llvm.aarch64.sve.fsub.nxv2f64(<vscale x 2 x i1> [[TMP1]], <vscale x 2 x double> [[A:%.*]], <vscale x 2 x double> [[B:%.*]]) #[[ATTR2]]
; CHECK-NEXT: ret <vscale x 2 x double> [[TMP2]]
;
%1 = tail call <vscale x 2 x i1> @llvm.aarch64.sve.ptrue.nxv2i1(i32 31) #1
%2 = tail call <vscale x 2 x double> @llvm.aarch64.sve.fsub.nxv2f64(<vscale x 2 x i1> %1, <vscale x 2 x double> %a, <vscale x 2 x double> %b) #1
Expand All @@ -71,8 +76,9 @@ define <vscale x 2 x double> @replace_fsub_intrinsic_double_strictfp(<vscale x 2
define <vscale x 2 x double> @call_replace_fsub_intrinsic_double_strictfp(<vscale x 2 x double> %a, <vscale x 2 x double> %b) #0 {
; CHECK: Function Attrs: strictfp
; CHECK-LABEL: @call_replace_fsub_intrinsic_double_strictfp(
; CHECK-NEXT: [[DOTSTRICT:%.*]] = call <vscale x 2 x double> @llvm.experimental.constrained.fsub.nxv2f64(<vscale x 2 x double> [[A:%.*]], <vscale x 2 x double> [[B:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR3]]
; CHECK-NEXT: ret <vscale x 2 x double> [[DOTSTRICT]]
; CHECK-NEXT: [[TMP1:%.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.ptrue.nxv2i1(i32 31) #[[ATTR2]]
; CHECK-NEXT: [[TMP2:%.*]] = call <vscale x 2 x double> @llvm.aarch64.sve.fsub.nxv2f64(<vscale x 2 x i1> [[TMP1]], <vscale x 2 x double> [[A:%.*]], <vscale x 2 x double> [[B:%.*]]) #[[ATTR2]]
; CHECK-NEXT: ret <vscale x 2 x double> [[TMP2]]
;
%1 = call <vscale x 2 x double> @replace_fsub_intrinsic_double_strictfp(<vscale x 2 x double> %a, <vscale x 2 x double> %b) #1
ret <vscale x 2 x double> %1
Expand All @@ -89,6 +95,5 @@ attributes #1 = { strictfp }
;.
; CHECK: attributes #[[ATTR0:[0-9]+]] = { strictfp "target-features"="+sve" }
; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(none) }
; CHECK: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) }
; CHECK: attributes #[[ATTR3]] = { strictfp }
; CHECK: attributes #[[ATTR2]] = { strictfp }
;.

0 comments on commit 65031c1

Please sign in to comment.