1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes 2; RUN: opt -aa-pipeline=basic-aa,globals-aa -passes='require<globals-aa>,gvn' -S < %s | FileCheck %s 3 4; Make sure we do not hoist the load before the intrinsic, unknown function, or 5; optnone function except if we know the unknown function is nosync and nocallback. 6 7@G1 = internal global i32 undef 8@G2 = internal global i32 undef 9@G3 = internal global i32 undef 10@G4 = internal global i32 undef 11 12define void @test_barrier(i1 %c) { 13; CHECK-LABEL: define {{[^@]+}}@test_barrier 14; CHECK-SAME: (i1 [[C:%.*]]) { 15; CHECK-NEXT: br i1 [[C]], label [[INIT:%.*]], label [[CHECK:%.*]] 16; CHECK: init: 17; CHECK-NEXT: store i32 0, ptr @G1, align 4 18; CHECK-NEXT: br label [[CHECK]] 19; CHECK: check: 20; CHECK-NEXT: call void @llvm.amdgcn.s.barrier() 21; CHECK-NEXT: [[V:%.*]] = load i32, ptr @G1, align 4 22; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V]], 0 23; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 24; CHECK-NEXT: ret void 25; 26 br i1 %c, label %init, label %check 27init: 28 store i32 0, ptr @G1 29 br label %check 30check: 31 call void @llvm.amdgcn.s.barrier() 32 %v = load i32, ptr @G1 33 %cmp = icmp eq i32 %v, 0 34 call void @llvm.assume(i1 %cmp) 35 ret void 36} 37 38define void @test_unknown(i1 %c) { 39; CHECK-LABEL: define {{[^@]+}}@test_unknown 40; CHECK-SAME: (i1 [[C:%.*]]) { 41; CHECK-NEXT: br i1 [[C]], label [[INIT:%.*]], label [[CHECK:%.*]] 42; CHECK: init: 43; CHECK-NEXT: store i32 0, ptr @G2, align 4 44; CHECK-NEXT: br label [[CHECK]] 45; CHECK: check: 46; CHECK-NEXT: call void @unknown() 47; CHECK-NEXT: [[V:%.*]] = load i32, ptr @G2, align 4 48; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V]], 0 49; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 50; CHECK-NEXT: ret void 51; 52 br i1 %c, label %init, label %check 53init: 54 store i32 0, ptr @G2 55 br label %check 56check: 57 call void @unknown() 58 %v = load i32, ptr @G2 59 %cmp = icmp eq i32 %v, 0 60 call void @llvm.assume(i1 %cmp) 61 ret void 62} 63 64define void @test_optnone(i1 %c) { 65; CHECK-LABEL: define {{[^@]+}}@test_optnone 66; CHECK-SAME: (i1 [[C:%.*]]) { 67; CHECK-NEXT: br i1 [[C]], label [[INIT:%.*]], label [[CHECK:%.*]] 68; CHECK: init: 69; CHECK-NEXT: store i32 0, ptr @G3, align 4 70; CHECK-NEXT: br label [[CHECK]] 71; CHECK: check: 72; CHECK-NEXT: call void @optnone() 73; CHECK-NEXT: [[V:%.*]] = load i32, ptr @G3, align 4 74; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V]], 0 75; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 76; CHECK-NEXT: ret void 77; 78 br i1 %c, label %init, label %check 79init: 80 store i32 0, ptr @G3 81 br label %check 82check: 83 call void @optnone() 84 %v = load i32, ptr @G3 85 %cmp = icmp eq i32 %v, 0 86 call void @llvm.assume(i1 %cmp) 87 ret void 88} 89 90define void @optnone() optnone nosync nocallback noinline { 91; CHECK: Function Attrs: nocallback noinline nosync optnone 92; CHECK-LABEL: define {{[^@]+}}@optnone 93; CHECK-SAME: () #[[ATTR0:[0-9]+]] { 94; CHECK-NEXT: ret void 95; 96 ret void 97} 98 99; Here hoisting is legal and we use it to verify it will happen. 100define void @test_unknown_annotated(i1 %c) { 101; CHECK-LABEL: define {{[^@]+}}@test_unknown_annotated 102; CHECK-SAME: (i1 [[C:%.*]]) { 103; CHECK-NEXT: br i1 [[C]], label [[INIT:%.*]], label [[DOTCHECK_CRIT_EDGE:%.*]] 104; CHECK: .check_crit_edge: 105; CHECK-NEXT: [[V_PRE:%.*]] = load i32, ptr @G4, align 4 106; CHECK-NEXT: br label [[CHECK:%.*]] 107; CHECK: init: 108; CHECK-NEXT: store i32 0, ptr @G4, align 4 109; CHECK-NEXT: br label [[CHECK]] 110; CHECK: check: 111; CHECK-NEXT: [[V:%.*]] = phi i32 [ [[V_PRE]], [[DOTCHECK_CRIT_EDGE]] ], [ 0, [[INIT]] ] 112; CHECK-NEXT: call void @unknown_nosync_nocallback() 113; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V]], 0 114; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 115; CHECK-NEXT: ret void 116; 117 br i1 %c, label %init, label %check 118init: 119 store i32 0, ptr @G4 120 br label %check 121check: 122 call void @unknown_nosync_nocallback() 123 %v = load i32, ptr @G4 124 %cmp = icmp eq i32 %v, 0 125 call void @llvm.assume(i1 %cmp) 126 ret void 127} 128 129declare void @unknown() 130declare void @unknown_nosync_nocallback() nosync nocallback 131declare void @llvm.amdgcn.s.barrier() 132declare void @llvm.assume(i1 noundef) 133 134