1; RUN: opt -basic-aa -print-memoryssa -verify-memoryssa -enable-new-pm=0 -analyze < %s 2>&1 | FileCheck %s 2; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>,verify<memoryssa>' -disable-output < %s 2>&1 | FileCheck %s 3; 4; Ensures that volatile stores/loads count as MemoryDefs 5 6; CHECK-LABEL: define i32 @foo 7define i32 @foo() { 8 %1 = alloca i32, align 4 9; CHECK: 1 = MemoryDef(liveOnEntry) 10; CHECK-NEXT: store volatile i32 4 11 store volatile i32 4, i32* %1, align 4 12; CHECK: 2 = MemoryDef(1) 13; CHECK-NEXT: store volatile i32 8 14 store volatile i32 8, i32* %1, align 4 15; CHECK: 3 = MemoryDef(2) 16; CHECK-NEXT: %2 = load volatile i32 17 %2 = load volatile i32, i32* %1, align 4 18; CHECK: 4 = MemoryDef(3) 19; CHECK-NEXT: %3 = load volatile i32 20 %3 = load volatile i32, i32* %1, align 4 21 %4 = add i32 %3, %2 22 ret i32 %4 23} 24 25; Ensuring we allow hoisting nonvolatile loads around volatile loads. 26; CHECK-LABEL: define void @volatile_only 27define void @volatile_only(i32* %arg1, i32* %arg2) { 28 ; Trivially NoAlias/MustAlias 29 %a = alloca i32 30 %b = alloca i32 31 32; CHECK: 1 = MemoryDef(liveOnEntry) 33; CHECK-NEXT: load volatile i32, i32* %a 34 load volatile i32, i32* %a 35; CHECK: MemoryUse(liveOnEntry) 36; CHECK-NEXT: load i32, i32* %b 37 load i32, i32* %b 38; CHECK: MemoryUse(liveOnEntry) 39; CHECK-NEXT: load i32, i32* %a 40 load i32, i32* %a 41 42 ; MayAlias 43; CHECK: 2 = MemoryDef(1) 44; CHECK-NEXT: load volatile i32, i32* %arg1 45 load volatile i32, i32* %arg1 46; CHECK: MemoryUse(liveOnEntry) 47; CHECK-NEXT: load i32, i32* %arg2 48 load i32, i32* %arg2 49 50 ret void 51} 52 53; Ensuring that volatile atomic operations work properly. 54; CHECK-LABEL: define void @volatile_atomics 55define void @volatile_atomics(i32* %arg1, i32* %arg2) { 56 %a = alloca i32 57 %b = alloca i32 58 59 ; Trivially NoAlias/MustAlias 60 61; CHECK: 1 = MemoryDef(liveOnEntry) 62; CHECK-NEXT: load atomic volatile i32, i32* %a acquire, align 4 63 load atomic volatile i32, i32* %a acquire, align 4 64; CHECK: MemoryUse(1) 65; CHECK-NEXT: load i32, i32* %b 66 load i32, i32* %b 67 68; CHECK: 2 = MemoryDef(1) 69; CHECK-NEXT: load atomic volatile i32, i32* %a monotonic, align 4 70 load atomic volatile i32, i32* %a monotonic, align 4 71; CHECK: MemoryUse(1) 72; CHECK-NEXT: load i32, i32* %b 73 load i32, i32* %b 74; CHECK: MemoryUse(1) 75; CHECK-NEXT: load atomic i32, i32* %b unordered, align 4 76 load atomic i32, i32* %b unordered, align 4 77; CHECK: MemoryUse(1) 78; CHECK-NEXT: load atomic i32, i32* %a unordered, align 4 79 load atomic i32, i32* %a unordered, align 4 80; CHECK: MemoryUse(1) 81; CHECK-NEXT: load i32, i32* %a 82 load i32, i32* %a 83 84 ; MayAlias 85; CHECK: 3 = MemoryDef(2) 86; CHECK-NEXT: load atomic volatile i32, i32* %arg1 monotonic, align 4 87 load atomic volatile i32, i32* %arg1 monotonic, align 4 88; CHECK: MemoryUse(1) 89; CHECK-NEXT: load i32, i32* %arg2 90 load i32, i32* %arg2 91 92 ret void 93} 94