93 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=sink -S < %s | FileCheck %s3 4; Loads marked invariant can be sunk across critical edges.5 6define <4 x float> @invariant_load(ptr %in, i32 %s) {7; CHECK-LABEL: @invariant_load(8; CHECK-NEXT: main_body:9; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[S:%.*]], 010; CHECK-NEXT: br i1 [[C]], label [[BLOCK:%.*]], label [[END:%.*]]11; CHECK: block:12; CHECK-NEXT: [[Z:%.*]] = add i32 [[S]], 113; CHECK-NEXT: br label [[END]]14; CHECK: end:15; CHECK-NEXT: [[V:%.*]] = load <4 x float>, ptr [[IN:%.*]], align 16, !invariant.load [[META0:![0-9]+]]16; CHECK-NEXT: ret <4 x float> [[V]]17;18main_body:19 %v = load <4 x float>, ptr %in, !invariant.load !020 %c = icmp eq i32 %s, 021 br i1 %c, label %block, label %end22block:23 %z = add i32 %s, 124 br label %end25end:26 ret <4 x float> %v27}28 29; Loads that aren't marked invariant but used in one branch30; can be sunk to that branch.31 32define void @invariant_load_use_in_br(ptr %p, i1 %cond) {33; CHECK-LABEL: @invariant_load_use_in_br(34; CHECK-NEXT: entry:35; CHECK-NEXT: br i1 [[COND:%.*]], label [[TRUE_BR:%.*]], label [[FALSE_BR:%.*]]36; CHECK: true.br:37; CHECK-NEXT: call void @fn()38; CHECK-NEXT: br label [[EXIT:%.*]]39; CHECK: false.br:40; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[P:%.*]], align 441; CHECK-NEXT: call void @fn(i32 [[VAL]])42; CHECK-NEXT: br label [[EXIT]]43; CHECK: exit:44; CHECK-NEXT: ret void45;46entry:47 %val = load i32, ptr %p48 br i1 %cond, label %true.br, label %false.br49true.br:50 call void @fn()51 br label %exit52false.br:53 call void @fn(i32 %val)54 br label %exit55exit:56 ret void57}58 59; TODO: Invariant loads marked with metadata can be sunk past calls.60 61define void @invariant_load_metadata_call(ptr %p, i1 %cond) {62; CHECK-LABEL: @invariant_load_metadata_call(63; CHECK-NEXT: entry:64; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[P:%.*]], align 4, !invariant.load [[META0]]65; CHECK-NEXT: call void @fn()66; CHECK-NEXT: br i1 [[COND:%.*]], label [[TRUE_BR:%.*]], label [[FALSE_BR:%.*]]67; CHECK: true.br:68; CHECK-NEXT: call void @fn()69; CHECK-NEXT: br label [[EXIT:%.*]]70; CHECK: false.br:71; CHECK-NEXT: call void @fn(i32 [[VAL]])72; CHECK-NEXT: br label [[EXIT]]73; CHECK: exit:74; CHECK-NEXT: ret void75;76entry:77 %val = load i32, ptr %p, !invariant.load !078 call void @fn()79 br i1 %cond, label %true.br, label %false.br80true.br:81 call void @fn()82 br label %exit83false.br:84 call void @fn(i32 %val)85 br label %exit86exit:87 ret void88}89 90declare void @fn()91 92!0 = !{}93