From 7fed6c6996ad99533152ec3f008bdf865c711f2b Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Thu, 17 Oct 2024 11:17:10 +0100 Subject: [PATCH] Sink/test: increase coverage of invariant-load Tests adapted from: https://discourse.llvm.org/t/sinking-does-any-llvm-pass-currently-handle-load-sinking-for-invariant-loads/79643 We don't add tests for llvm.invariant.{start,end} though, as these are very difficult to support architecturally. --- llvm/test/Transforms/Sink/invariant-load.ll | 67 ++++++++++++++++++++- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/llvm/test/Transforms/Sink/invariant-load.ll b/llvm/test/Transforms/Sink/invariant-load.ll index 1aab4a9696323..c8fb119acd30a 100644 --- a/llvm/test/Transforms/Sink/invariant-load.ll +++ b/llvm/test/Transforms/Sink/invariant-load.ll @@ -1,7 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -passes=sink -S < %s | FileCheck %s -; Loads marked invariant can be sunk across critical edges +; Loads marked invariant can be sunk across critical edges. define <4 x float> @invariant_load(ptr %in, i32 %s) { ; CHECK-LABEL: @invariant_load( @@ -12,7 +12,7 @@ define <4 x float> @invariant_load(ptr %in, i32 %s) { ; CHECK-NEXT: [[Z:%.*]] = add i32 [[S]], 1 ; CHECK-NEXT: br label [[END]] ; CHECK: end: -; CHECK-NEXT: [[V:%.*]] = load <4 x float>, ptr [[IN:%.*]], align 16, !invariant.load !0 +; CHECK-NEXT: [[V:%.*]] = load <4 x float>, ptr [[IN:%.*]], align 16, !invariant.load [[META0:![0-9]+]] ; CHECK-NEXT: ret <4 x float> [[V]] ; main_body: @@ -26,4 +26,67 @@ end: ret <4 x float> %v } +; Loads that aren't marked invariant but used in one branch +; can be sunk to that branch. + +define void @invariant_load_use_in_br(ptr %p, i1 %cond) { +; CHECK-LABEL: @invariant_load_use_in_br( +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 [[COND:%.*]], label [[TRUE_BR:%.*]], label [[FALSE_BR:%.*]] +; CHECK: true.br: +; CHECK-NEXT: call void @fn() +; CHECK-NEXT: br label [[EXIT:%.*]] +; CHECK: false.br: +; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[P:%.*]], align 4 +; CHECK-NEXT: call void @fn(i32 [[VAL]]) +; CHECK-NEXT: br label [[EXIT]] +; CHECK: exit: +; CHECK-NEXT: ret void +; +entry: + %val = load i32, ptr %p + br i1 %cond, label %true.br, label %false.br +true.br: + call void @fn() + br label %exit +false.br: + call void @fn(i32 %val) + br label %exit +exit: + ret void +} + +; TODO: Invariant loads marked with metadata can be sunk past calls. + +define void @invariant_load_metadata_call(ptr %p, i1 %cond) { +; CHECK-LABEL: @invariant_load_metadata_call( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[P:%.*]], align 4, !invariant.load [[META0]] +; CHECK-NEXT: call void @fn() +; CHECK-NEXT: br i1 [[COND:%.*]], label [[TRUE_BR:%.*]], label [[FALSE_BR:%.*]] +; CHECK: true.br: +; CHECK-NEXT: call void @fn() +; CHECK-NEXT: br label [[EXIT:%.*]] +; CHECK: false.br: +; CHECK-NEXT: call void @fn(i32 [[VAL]]) +; CHECK-NEXT: br label [[EXIT]] +; CHECK: exit: +; CHECK-NEXT: ret void +; +entry: + %val = load i32, ptr %p, !invariant.load !0 + call void @fn() + br i1 %cond, label %true.br, label %false.br +true.br: + call void @fn() + br label %exit +false.br: + call void @fn(i32 %val) + br label %exit +exit: + ret void +} + +declare void @fn() + !0 = !{}