1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes 2; RUN: opt -S -passes=argpromotion < %s | FileCheck %s 3 4define internal i32 @callee_basic(ptr %p) { 5; CHECK-LABEL: define {{[^@]+}}@callee_basic 6; CHECK-SAME: (i32 [[P_0_VAL:%.*]], i32 [[P_4_VAL:%.*]]) { 7; CHECK-NEXT: [[Z:%.*]] = add i32 [[P_0_VAL]], [[P_4_VAL]] 8; CHECK-NEXT: ret i32 [[Z]] 9; 10 %x = load i32, ptr %p 11 %p1 = getelementptr i8, ptr %p, i64 4 12 %y = load i32, ptr %p1 13 %z = add i32 %x, %y 14 ret i32 %z 15} 16 17define void @caller_basic(ptr %p) { 18; CHECK-LABEL: define {{[^@]+}}@caller_basic 19; CHECK-SAME: (ptr [[P:%.*]]) { 20; CHECK-NEXT: [[P_VAL:%.*]] = load i32, ptr [[P]], align 4 21; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[P]], i64 4 22; CHECK-NEXT: [[P_VAL1:%.*]] = load i32, ptr [[TMP1]], align 4 23; CHECK-NEXT: [[TMP2:%.*]] = call i32 @callee_basic(i32 [[P_VAL]], i32 [[P_VAL1]]) 24; CHECK-NEXT: ret void 25; 26 call i32 @callee_basic(ptr %p) 27 ret void 28} 29 30; Same offset is loaded with two differen types: Don't promote. 31define internal i32 @callee_different_types(ptr %p) { 32; CHECK-LABEL: define {{[^@]+}}@callee_different_types 33; CHECK-SAME: (ptr [[P:%.*]]) { 34; CHECK-NEXT: [[X:%.*]] = load i32, ptr [[P]], align 4 35; CHECK-NEXT: [[Y_F:%.*]] = load float, ptr [[P]], align 4 36; CHECK-NEXT: [[Y:%.*]] = fptoui float [[Y_F]] to i32 37; CHECK-NEXT: [[Z:%.*]] = add i32 [[X]], [[Y]] 38; CHECK-NEXT: ret i32 [[Z]] 39; 40 %x = load i32, ptr %p 41 %y.f = load float, ptr %p 42 %y = fptoui float %y.f to i32 43 %z = add i32 %x, %y 44 ret i32 %z 45} 46 47define void @caller_different_types(ptr %p) { 48; CHECK-LABEL: define {{[^@]+}}@caller_different_types 49; CHECK-SAME: (ptr [[P:%.*]]) { 50; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_different_types(ptr [[P]]) 51; CHECK-NEXT: ret void 52; 53 call i32 @callee_different_types(ptr %p) 54 ret void 55} 56 57; The two loads overlap: Don't promote. 58define internal i32 @callee_overlap(ptr %p) { 59; CHECK-LABEL: define {{[^@]+}}@callee_overlap 60; CHECK-SAME: (ptr [[P:%.*]]) { 61; CHECK-NEXT: [[X:%.*]] = load i32, ptr [[P]], align 4 62; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[P]], i64 2 63; CHECK-NEXT: [[Y:%.*]] = load i32, ptr [[P1]], align 4 64; CHECK-NEXT: [[Z:%.*]] = add i32 [[X]], [[Y]] 65; CHECK-NEXT: ret i32 [[Z]] 66; 67 %x = load i32, ptr %p 68 %p1 = getelementptr i8, ptr %p, i64 2 69 %y = load i32, ptr %p1 70 %z = add i32 %x, %y 71 ret i32 %z 72} 73 74define void @caller_overlap(ptr %p) { 75; CHECK-LABEL: define {{[^@]+}}@caller_overlap 76; CHECK-SAME: (ptr [[P:%.*]]) { 77; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_overlap(ptr [[P]]) 78; CHECK-NEXT: ret void 79; 80 call i32 @callee_overlap(ptr %p) 81 ret void 82} 83 84; Don't promote calls with function type mismatch. 85define void @caller_type_mismatch() { 86; CHECK-LABEL: define {{[^@]+}}@caller_type_mismatch() { 87; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_type_mismatch(ptr null) 88; CHECK-NEXT: ret void 89; 90 call i32 @callee_type_mismatch(ptr null) 91 ret void 92} 93 94define internal void @callee_type_mismatch(ptr %p) { 95; CHECK-LABEL: define {{[^@]+}}@callee_type_mismatch 96; CHECK-SAME: (ptr [[P:%.*]]) { 97; CHECK-NEXT: ret void 98; 99 ret void 100} 101