1; Test to ensure no inlining is allowed into a caller with fewer nobuiltin attributes. 2; RUN: opt < %s -mtriple=x86_64-unknown-linux-gnu -S -inline | FileCheck %s 3; RUN: opt < %s -mtriple=x86_64-unknown-linux-gnu -S -passes='cgscc(inline)' | FileCheck %s 4 5; Make sure we don't inline callees into a caller with a superset of the 6; no builtin attributes when -inline-caller-superset-nobuiltin=false. 7; RUN: opt < %s -inline-caller-superset-nobuiltin=false -mtriple=x86_64-unknown-linux-gnu -S -passes='cgscc(inline)' | FileCheck %s --check-prefix=NOSUPERSET 8 9target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 10target triple = "x86_64-unknown-linux-gnu" 11 12define i32 @allbuiltins() { 13entry: 14 %call = call i32 (...) @externalfunc() 15 ret i32 %call 16; CHECK-LABEL: allbuiltins 17; CHECK: call i32 (...) @externalfunc() 18} 19declare i32 @externalfunc(...) 20 21; We can inline a function that allows all builtins into one with a single 22; nobuiltin. 23define i32 @nobuiltinmemcpy() #0 { 24entry: 25 %call = call i32 @allbuiltins() 26 ret i32 %call 27; CHECK-LABEL: nobuiltinmemcpy 28; CHECK-NOT: call i32 @allbuiltins() 29; NOSUPERSET-LABEL: nobuiltinmemcpy 30; NOSUPERSET: call i32 @allbuiltins() 31} 32 33; We can inline a function that allows all builtins into one with all 34; nobuiltins. 35define i32 @nobuiltins() #1 { 36entry: 37 %call = call i32 @allbuiltins() 38 ret i32 %call 39; CHECK-LABEL: nobuiltins 40; CHECK-NOT: call i32 @allbuiltins() 41; NOSUPERSET-LABEL: nobuiltins 42; NOSUPERSET: call i32 @allbuiltins() 43} 44 45; We can inline a function with a single nobuiltin into one with all nobuiltins. 46define i32 @nobuiltins2() #1 { 47entry: 48 %call = call i32 @nobuiltinmemcpy() 49 ret i32 %call 50; CHECK-LABEL: nobuiltins2 51; CHECK-NOT: call i32 @nobuiltinmemcpy() 52; NOSUPERSET-LABEL: nobuiltins2 53; NOSUPERSET: call i32 @nobuiltinmemcpy() 54} 55 56; We can't inline a function with any given nobuiltin into one that allows all 57; builtins. 58define i32 @allbuiltins2() { 59entry: 60 %call = call i32 @nobuiltinmemcpy() 61 ret i32 %call 62; CHECK-LABEL: allbuiltins2 63; CHECK: call i32 @nobuiltinmemcpy() 64; NOSUPERSET-LABEL: allbuiltins2 65; NOSUPERSET: call i32 @nobuiltinmemcpy() 66} 67 68; We can't inline a function with all nobuiltins into one that allows all 69; builtins. 70define i32 @allbuiltins3() { 71entry: 72 %call = call i32 @nobuiltins() 73 ret i32 %call 74; CHECK-LABEL: allbuiltins3 75; CHECK: call i32 @nobuiltins() 76; NOSUPERSET-LABEL: allbuiltins3 77; NOSUPERSET: call i32 @nobuiltins() 78} 79 80; We can't inline a function with a specific nobuiltin into one with a 81; different specific nobuiltin. 82define i32 @nobuiltinmemset() #2 { 83entry: 84 %call = call i32 @nobuiltinmemcpy() 85 ret i32 %call 86; CHECK-LABEL: nobuiltinmemset 87; CHECK: call i32 @nobuiltinmemcpy() 88; NOSUPERSET-LABEL: nobuiltinmemset 89; NOSUPERSET: call i32 @nobuiltinmemcpy() 90} 91 92attributes #0 = { "no-builtin-memcpy" } 93attributes #1 = { "no-builtins" } 94attributes #2 = { "no-builtin-memset" } 95