diff --git a/llvm/lib/Target/AIE/AIE2TargetTransformInfo.h b/llvm/lib/Target/AIE/AIE2TargetTransformInfo.h index 5adee9b9a00b..ab11c13be61e 100644 --- a/llvm/lib/Target/AIE/AIE2TargetTransformInfo.h +++ b/llvm/lib/Target/AIE/AIE2TargetTransformInfo.h @@ -62,6 +62,15 @@ class AIE2TTIImpl : public BasicTTIImplBase { bool isProfitableOuterLSR(const Loop &L) const; std::optional instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const; + + // By returning false here, we will prevent the following type + // of code from reaching the backend when GEPs are used as incoming values: + // for.body: ; preds = %for.body, %for.preheader + // %phi0 = phi ptr [ %in0, %for.body ], [ %out0, %for.preheader ] + // %phi1 = phi ptr [ %phi0, %for.body ], [ %out1, %for.preheader ] + // This type of code can lead to additional pointer arithmetics and + // and pointer moves (especially due to the pre-pipeliner). + bool isProfitableFoldGEPIntoPHI() const { return false; } }; } // end namespace llvm diff --git a/llvm/test/CodeGen/AIE/aie2/aie2-prevent-gep-phi-folding.ll b/llvm/test/CodeGen/AIE/aie2/aie2-prevent-gep-phi-folding.ll new file mode 100644 index 000000000000..542d1bac275a --- /dev/null +++ b/llvm/test/CodeGen/AIE/aie2/aie2-prevent-gep-phi-folding.ll @@ -0,0 +1,47 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; +; This file is licensed under the Apache License v2.0 with LLVM Exceptions. +; See https://llvm.org/LICENSE.txt for license information. +; SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +; +; (c) Copyright 2024 Advanced Micro Devices, Inc. or its affiliates +; RUN: opt -mtriple=aie2 -passes=instcombine -S < %s | FileCheck %s + +%struct = type { i32, i32 } + +define i32 @dontFoldGEPs(ptr %dm, i1 %arg4, i64 %arg9, i64 %arg19) { +; CHECK-LABEL: define i32 @dontFoldGEPs( +; CHECK-SAME: ptr [[DM:%.*]], i1 [[ARG4:%.*]], i64 [[ARG9:%.*]], i64 [[ARG19:%.*]]) { +; CHECK-NEXT: bb: +; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DM]], align 8 +; CHECK-NEXT: br i1 [[ARG4]], label [[BB1:%.*]], label [[BB2:%.*]] +; CHECK: bb1: +; CHECK-NEXT: [[TMP0:%.*]] = trunc i64 [[ARG9]] to i20 +; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT2:%.*]], ptr [[TMP1]], i20 [[TMP0]] +; CHECK-NEXT: br label [[BB3:%.*]] +; CHECK: bb2: +; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[ARG19]] to i20 +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT2]], ptr [[TMP1]], i20 [[TMP2]] +; CHECK-NEXT: br label [[BB3]] +; CHECK: bb3: +; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[TMP10]], [[BB1]] ], [ [[TMP4]], [[BB2]] ] +; CHECK-NEXT: [[TMP25:%.*]] = load i32, ptr [[PHI]], align 4 +; CHECK-NEXT: ret i32 [[TMP25]] +; +bb: + %0 = load ptr, ptr %dm, align 8 + br i1 %arg4, label %bb1, label %bb2 + +bb1: + %1 = getelementptr inbounds %struct, ptr %0, i64 %arg9 + br label %bb3 + +bb2: + %2 = getelementptr inbounds %struct, ptr %0, i64 %arg19 + br label %bb3 + +bb3: + %phi = phi ptr [ %1, %bb1 ], [ %2, %bb2 ] + %3 = load i32, ptr %phi, align 4 + ret i32 %3 +}