diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h --- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h +++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -448,13 +448,15 @@ // Identity and pointer-to-pointer casts are free. return 0; break; - case Instruction::Trunc: + case Instruction::Trunc: { // trunc to a native type is free (assuming the target has compare and // shift-right of the same width). - if (DL.isLegalInteger(DL.getTypeSizeInBits(Dst))) + TypeSize DstSize = DL.getTypeSizeInBits(Dst); + if (!DstSize.isScalable() && DL.isLegalInteger(DstSize.getFixedSize())) return 0; break; } + } return 1; } diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -130,6 +130,9 @@ if (Depth == MaxAnalysisRecursionDepth) return nullptr; + if (isa(VTy)) + return nullptr; + Instruction *I = dyn_cast(V); if (!I) { computeKnownBits(V, Known, Depth, CxtI); diff --git a/llvm/test/Analysis/CostModel/AArch64/sve-trunc.ll b/llvm/test/Analysis/CostModel/AArch64/sve-trunc.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Analysis/CostModel/AArch64/sve-trunc.ll @@ -0,0 +1,14 @@ +; RUN: opt -mtriple=aarch64-linux-gnu -mattr=+sve -cost-model -analyze < %s 2>%t | FileCheck %s +; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t + +; If this check fails please read test/CodeGen/AArch64/README for instructions on how to resolve it. +; WARN-NOT: warning + +; CHECK: Found an estimated cost of 0 for instruction: %0 = trunc %v to + +define void @trunc_nxv2i64_to_nxv2i32(* %ptr, %v) { +entry: + %0 = trunc %v to + store %0, * %ptr + ret void +} diff --git a/llvm/test/Transforms/InstCombine/AArch64/sve-trunc.ll b/llvm/test/Transforms/InstCombine/AArch64/sve-trunc.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/AArch64/sve-trunc.ll @@ -0,0 +1,29 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -mtriple aarch64-linux-gnu -mattr=+sve -instcombine -S < %s 2>%t | FileCheck %s +; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t + +; If this check fails please read test/CodeGen/AArch64/README for instructions on how to resolve it. +; WARN-NOT: warning + +define void @trunc_nxv2i64_to_nxv2i32(i32* %ptr, %v) { +; CHECK-LABEL: @trunc_nxv2i64_to_nxv2i32( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 31) +; CHECK-NEXT: [[TMP1:%.*]] = bitcast [[V:%.*]] to +; CHECK-NEXT: [[TMP2:%.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( [[TMP0]]) +; CHECK-NEXT: [[TMP3:%.*]] = trunc [[TMP1]] to +; CHECK-NEXT: call void @llvm.aarch64.sve.st1.nxv2i32( [[TMP3]], [[TMP2]], i32* [[PTR:%.*]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 31) + %1 = bitcast %v to + %2 = call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( %0) + %3 = trunc %1 to + call void @llvm.aarch64.sve.st1.nxv2i32( %3, %2, i32* %ptr) + ret void +} + +declare void @llvm.aarch64.sve.st1.nxv2i32(, , i32*) +declare @llvm.aarch64.sve.convert.from.svbool.nxv2i1() +declare @llvm.aarch64.sve.ptrue.nxv16i1(i32 %pattern)