1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes='require<profile-summary>,function(codegenprepare)' -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s 3; REQUIRES: aarch64-registered-target 4 5%struct.S = type { i8 } 6%struct.X = type { i32 } 7 8@g_getS = internal global %struct.S zeroinitializer, align 1 9@g_getX = internal global %struct.X zeroinitializer, align 1 10@guard = internal global i64 0, align 8 11 12declare ptr @getS_dec() 13declare extern_weak dllimport ptr @getS_dllimport_function() 14 15define ptr @getS() personality ptr @__gxx_personality_v0 { 16entry: 17 %guard = load atomic i8, ptr @guard acquire, align 8 18 %mask = and i8 %guard, 1 19 %cond = icmp eq i8 %mask, 0 20 br i1 %cond, label %to_be_init, label %return 21 22to_be_init: ; preds = %entry 23 %is_init = call i32 @__cxa_guard_acquire(ptr @guard) 24 %cond.2 = icmp ne i32 %is_init, 0 25 br i1 %cond.2, label %ctor, label %return 26 27ctor: ; preds = %to_be_init 28 invoke void @S_ctor(ptr @g_getS) 29 to label %continue unwind label %landing_pad 30 31continue: ; preds = %ctor 32 call void @__cxa_guard_release(ptr @guard) 33 br label %return 34 35return: ; preds = %continue, %to_be_init, %entry 36 ret ptr @g_getS 37 38landing_pad: ; preds = %ctor 39 %lp = landingpad { ptr, i32 } cleanup 40 call void @__cxa_guard_abort(ptr @guard) 41 resume { ptr, i32 } %lp 42} 43 44define ptr @getS_or_getX(i1 %cond) { 45entry: 46 %result = select i1 %cond, ptr @g_getS, ptr @g_getX 47 ret ptr %result 48} 49 50define weak ptr @getS_weak_function() { 51entry: 52 ret ptr @g_getS 53} 54 55define linkonce_odr ptr @getS_linkonce_odr_function() { 56entry: 57 ret ptr @g_getS 58} 59 60; May revert propagation. 61define i32 @caller_1() { 62; CHECK-LABEL: @caller_1( 63; CHECK-NEXT: [[GETS_PTR:%.*]] = call ptr @getS() 64; CHECK-NEXT: [[GETI:%.*]] = call i32 @S_getI(ptr [[GETS_PTR]]) 65; CHECK-NEXT: ret i32 [[GETI]] 66; 67 %getS_ptr = call ptr @getS() 68 %getI = call i32 @S_getI(ptr @g_getS) 69 ret i32 %getI 70} 71 72; Cannot revert propagation due to use appearing in a different basic block. 73define i32 @caller_2() { 74; CHECK-LABEL: @caller_2( 75; CHECK-NEXT: entry: 76; CHECK-NEXT: [[GETS_PTR:%.*]] = call ptr @getS() 77; CHECK-NEXT: br label [[USE:%.*]] 78; CHECK: use: 79; CHECK-NEXT: [[GETI:%.*]] = call i32 @S_getI(ptr [[GETS_PTR]]) 80; CHECK-NEXT: ret i32 [[GETI]] 81; 82entry: 83 %getS_ptr = call ptr @getS() 84 br label %use 85 86use: ; preds = %entry 87 %getI = call i32 @S_getI(ptr %getS_ptr) 88 ret i32 %getI 89} 90 91; Cannot revert propagation due to use before call. 92define i32 @caller_3() { 93; CHECK-LABEL: @caller_3( 94; CHECK-NEXT: entry: 95; CHECK-NEXT: [[GETI:%.*]] = call i32 @S_getI(ptr @g_getS) 96; CHECK-NEXT: [[GETS_PTR:%.*]] = call ptr @getS() 97; CHECK-NEXT: ret i32 [[GETI]] 98; 99entry: 100 %getI = call i32 @S_getI(ptr @g_getS) 101 %getS_ptr = call ptr @getS() 102 ret i32 %getI 103} 104 105; Cannot revert propagation due to non-uniform returned constant. 106define i32 @caller_4(i1 %cond) { 107; CHECK-LABEL: @caller_4( 108; CHECK-NEXT: [[GETS_OR_GETX_PTR:%.*]] = call ptr @getS_or_getX(i1 [[COND:%.*]]) 109; CHECK-NEXT: [[GETI:%.*]] = call i32 @S_getI(ptr @g_getS) 110; CHECK-NEXT: ret i32 [[GETI]] 111; 112 %getS_or_getX_ptr = call ptr @getS_or_getX(i1 %cond) 113 %getI = call i32 @S_getI(ptr @g_getS) 114 ret i32 %getI 115} 116 117; Cannot revert propagation due to weak-linkage callee. 118define i32 @caller_5() { 119; CHECK-LABEL: @caller_5( 120; CHECK-NEXT: [[GETS_PTR:%.*]] = call ptr @getS_weak_function() 121; CHECK-NEXT: [[GETI:%.*]] = call i32 @S_getI(ptr @g_getS) 122; CHECK-NEXT: ret i32 [[GETI]] 123; 124 %getS_ptr = call ptr @getS_weak_function() 125 %getI = call i32 @S_getI(ptr @g_getS) 126 ret i32 %getI 127} 128 129; Cannot revert propagation due to callee with external function definition. 130define i32 @caller_6() { 131; CHECK-LABEL: @caller_6( 132; CHECK-NEXT: [[GETS_PTR:%.*]] = call ptr @getS_dec() 133; CHECK-NEXT: [[GETI:%.*]] = call i32 @S_getI(ptr @g_getS) 134; CHECK-NEXT: ret i32 [[GETI]] 135; 136 %getS_ptr = call ptr @getS_dec() 137 %getI = call i32 @S_getI(ptr @g_getS) 138 ret i32 %getI 139} 140 141; Cannot revert propagation due to callee with DLLImport storage class. 142define i32 @caller_7() { 143; CHECK-LABEL: @caller_7( 144; CHECK-NEXT: [[GETS_PTR:%.*]] = call ptr @getS_dllimport_function() 145; CHECK-NEXT: [[GETI:%.*]] = call i32 @S_getI(ptr @g_getS) 146; CHECK-NEXT: ret i32 [[GETI]] 147; 148 %getS_ptr = call ptr @getS_dllimport_function() 149 %getI = call i32 @S_getI(ptr @g_getS) 150 ret i32 %getI 151} 152 153; Cannot revert propagation due to callee whose definition may be overridden. 154define i32 @caller_8() { 155; CHECK-LABEL: @caller_8( 156; CHECK-NEXT: [[GETS_PTR:%.*]] = call ptr @getS_linkonce_odr_function() 157; CHECK-NEXT: [[GETI:%.*]] = call i32 @S_getI(ptr @g_getS) 158; CHECK-NEXT: ret i32 [[GETI]] 159; 160 %getS_ptr = call ptr @getS_linkonce_odr_function() 161 %getI = call i32 @S_getI(ptr @g_getS) 162 ret i32 %getI 163} 164 165declare i32 @__cxa_guard_acquire(ptr) 166declare void @S_ctor(ptr) 167declare i32 @S_getI(ptr) 168declare void @__cxa_guard_abort(ptr) 169declare void @__cxa_guard_release(ptr) 170declare i32 @__gxx_personality_v0(...) 171