1; RUN: opt -O3 -S < %s | FileCheck %s 2; Show 'optnone' suppresses optimizations. 3 4; Two attribute groups that differ only by 'optnone'. 5; 'optnone' requires 'noinline' so #0 is 'noinline' by itself, 6; even though it would otherwise be irrelevant to this example. 7attributes #0 = { noinline } 8attributes #1 = { noinline optnone } 9 10; int iadd(int a, int b){ return a + b; } 11 12define i32 @iadd_optimize(i32 %a, i32 %b) #0 { 13entry: 14 %a.addr = alloca i32, align 4 15 %b.addr = alloca i32, align 4 16 store i32 %a, i32* %a.addr, align 4 17 store i32 %b, i32* %b.addr, align 4 18 %0 = load i32, i32* %a.addr, align 4 19 %1 = load i32, i32* %b.addr, align 4 20 %add = add nsw i32 %0, %1 21 ret i32 %add 22} 23 24; CHECK-LABEL: @iadd_optimize 25; CHECK-NOT: alloca 26; CHECK-NOT: store 27; CHECK-NOT: load 28; CHECK: ret 29 30define i32 @iadd_optnone(i32 %a, i32 %b) #1 { 31entry: 32 %a.addr = alloca i32, align 4 33 %b.addr = alloca i32, align 4 34 store i32 %a, i32* %a.addr, align 4 35 store i32 %b, i32* %b.addr, align 4 36 %0 = load i32, i32* %a.addr, align 4 37 %1 = load i32, i32* %b.addr, align 4 38 %add = add nsw i32 %0, %1 39 ret i32 %add 40} 41 42; CHECK-LABEL: @iadd_optnone 43; CHECK: alloca i32 44; CHECK: alloca i32 45; CHECK: store i32 46; CHECK: store i32 47; CHECK: load i32 48; CHECK: load i32 49; CHECK: add nsw i32 50; CHECK: ret i32 51 52; float fsub(float a, float b){ return a - b; } 53 54define float @fsub_optimize(float %a, float %b) #0 { 55entry: 56 %a.addr = alloca float, align 4 57 %b.addr = alloca float, align 4 58 store float %a, float* %a.addr, align 4 59 store float %b, float* %b.addr, align 4 60 %0 = load float, float* %a.addr, align 4 61 %1 = load float, float* %b.addr, align 4 62 %sub = fsub float %0, %1 63 ret float %sub 64} 65 66; CHECK-LABEL: @fsub_optimize 67; CHECK-NOT: alloca 68; CHECK-NOT: store 69; CHECK-NOT: load 70; CHECK: ret 71 72define float @fsub_optnone(float %a, float %b) #1 { 73entry: 74 %a.addr = alloca float, align 4 75 %b.addr = alloca float, align 4 76 store float %a, float* %a.addr, align 4 77 store float %b, float* %b.addr, align 4 78 %0 = load float, float* %a.addr, align 4 79 %1 = load float, float* %b.addr, align 4 80 %sub = fsub float %0, %1 81 ret float %sub 82} 83 84; CHECK-LABEL: @fsub_optnone 85; CHECK: alloca float 86; CHECK: alloca float 87; CHECK: store float 88; CHECK: store float 89; CHECK: load float 90; CHECK: load float 91; CHECK: fsub float 92; CHECK: ret float 93 94; typedef float __attribute__((ext_vector_type(4))) float4; 95; float4 vmul(float4 a, float4 b){ return a * b; } 96 97define <4 x float> @vmul_optimize(<4 x float> %a, <4 x float> %b) #0 { 98entry: 99 %a.addr = alloca <4 x float>, align 16 100 %b.addr = alloca <4 x float>, align 16 101 store <4 x float> %a, <4 x float>* %a.addr, align 16 102 store <4 x float> %b, <4 x float>* %b.addr, align 16 103 %0 = load <4 x float>, <4 x float>* %a.addr, align 16 104 %1 = load <4 x float>, <4 x float>* %b.addr, align 16 105 %mul = fmul <4 x float> %0, %1 106 ret <4 x float> %mul 107} 108 109; CHECK-LABEL: @vmul_optimize 110; CHECK-NOT: alloca 111; CHECK-NOT: store 112; CHECK-NOT: load 113; CHECK: ret 114 115define <4 x float> @vmul_optnone(<4 x float> %a, <4 x float> %b) #1 { 116entry: 117 %a.addr = alloca <4 x float>, align 16 118 %b.addr = alloca <4 x float>, align 16 119 store <4 x float> %a, <4 x float>* %a.addr, align 16 120 store <4 x float> %b, <4 x float>* %b.addr, align 16 121 %0 = load <4 x float>, <4 x float>* %a.addr, align 16 122 %1 = load <4 x float>, <4 x float>* %b.addr, align 16 123 %mul = fmul <4 x float> %0, %1 124 ret <4 x float> %mul 125} 126 127; CHECK-LABEL: @vmul_optnone 128; CHECK: alloca <4 x float> 129; CHECK: alloca <4 x float> 130; CHECK: store <4 x float> 131; CHECK: store <4 x float> 132; CHECK: load <4 x float> 133; CHECK: load <4 x float> 134; CHECK: fmul <4 x float> 135; CHECK: ret 136