From db5b7915959a45951c3e6a0d5cc61f0f4ddfe291 Mon Sep 17 00:00:00 2001 From: Brendon Cahoon Date: Tue, 4 Jan 2022 11:40:30 -0800 Subject: [PATCH] [Hexagon] Fix an instruction move in HexagonVectorCombine The HexagonVectorCombine pass was moving an instruction incorrectly, which caused a use in a GEP that was not yet defined. HexagonVectorCombine removes a load from a group due to its dependences, but in realignGroup, the load is processed anyways. In realignGroup, when determining the maximum alignment, only those instructions still in the group should be considered. --- llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp | 2 +- .../Hexagon/autohvx/vector-align-bad-move.ll | 45 ++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/Hexagon/autohvx/vector-align-bad-move.ll diff --git a/llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp b/llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp index 755ad96..bc64d9d 100644 --- a/llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp +++ b/llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp @@ -718,7 +718,7 @@ auto AlignVectors::realignGroup(const MoveGroup &Move) const -> bool { // Maximum alignment present in the whole address group. const AddrInfo &WithMaxAlign = - getMaxOf(BaseInfos, [](const AddrInfo &AI) { return AI.HaveAlign; }); + getMaxOf(MoveInfos, [](const AddrInfo &AI) { return AI.HaveAlign; }); Align MaxGiven = WithMaxAlign.HaveAlign; // Minimum alignment present in the move address group. diff --git a/llvm/test/CodeGen/Hexagon/autohvx/vector-align-bad-move.ll b/llvm/test/CodeGen/Hexagon/autohvx/vector-align-bad-move.ll new file mode 100644 index 0000000..8da468a --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/autohvx/vector-align-bad-move.ll @@ -0,0 +1,45 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s +; REQUIRES: asserts + +; Test that the HexagonVectorCombine pass does not move an instruction +; incorrectly, which causes a GEP to have a base that is not defined. +; If the pass runs correctly, the unaligned loads are converted to +; aligned loads instead of crashing. + +; CHECK-NOT: vmemu + +define dllexport void @test() local_unnamed_addr #0 { +entry: + br label %for_begin77 + +for_begin77: + %0 = load i8*, i8** undef, align 4 + %1 = getelementptr i8, i8* %0, i32 1794 + %2 = bitcast i8* %1 to <64 x half>* + %3 = call <64 x half> @llvm.masked.load.v64f16.p0v64f16(<64 x half>* %2, i32 1, <64 x i1> , <64 x half> undef) + %4 = getelementptr i8, i8* %0, i32 1922 + %5 = bitcast i8* %4 to <64 x half>* + %6 = call <64 x half> @llvm.masked.load.v64f16.p0v64f16(<64 x half>* %5, i32 1, <64 x i1> , <64 x half> undef) + %7 = shufflevector <64 x half> %3, <64 x half> %6, <64 x i32> + call void @llvm.assume(i1 true) [ "align"(i8* null, i32 128) ] + %8 = getelementptr i8, i8* null, i32 128 + %9 = bitcast i8* %8 to <64 x half>* + %10 = fadd <64 x half> zeroinitializer, %7 + %11 = shufflevector <64 x half> %10, <64 x half> undef, <64 x i32> + %12 = getelementptr i8, i8* %0, i32 1920 + %13 = bitcast i8* %12 to <64 x half>* + %unmaskedload243 = load <64 x half>, <64 x half>* %13, align 128 + %14 = fadd <64 x half> %11, %unmaskedload243 + store <64 x half> %14, <64 x half>* %9, align 128 + br label %for_begin77 +} + +; Function Attrs: nofree nosync nounwind willreturn +declare void @llvm.assume(i1 noundef) #1 + +; Function Attrs: argmemonly nofree nosync nounwind readonly willreturn +declare <64 x half> @llvm.masked.load.v64f16.p0v64f16(<64 x half>*, i32 immarg, <64 x i1>, <64 x half>) #2 + +attributes #0 = { "target-features"="+hvxv68,+hvx-length128b,+hvx-qfloat" } +attributes #1 = { nofree nosync nounwind willreturn } +attributes #2 = { argmemonly nofree nosync nounwind readonly willreturn } -- 2.7.4