|  | ; RUN: opt -O3 -S < %s | FileCheck %s | 
|  | ; Show 'optnone' suppresses optimizations. | 
|  |  | 
|  | ; Two attribute groups that differ only by 'optnone'. | 
|  | ; 'optnone' requires 'noinline' so #0 is 'noinline' by itself, | 
|  | ; even though it would otherwise be irrelevant to this example. | 
|  | attributes #0 = { noinline } | 
|  | attributes #1 = { noinline optnone } | 
|  |  | 
|  | ; int iadd(int a, int b){ return a + b; } | 
|  |  | 
|  | define i32 @iadd_optimize(i32 %a, i32 %b) #0 { | 
|  | entry: | 
|  | %a.addr = alloca i32, align 4 | 
|  | %b.addr = alloca i32, align 4 | 
|  | store i32 %a, i32* %a.addr, align 4 | 
|  | store i32 %b, i32* %b.addr, align 4 | 
|  | %0 = load i32, i32* %a.addr, align 4 | 
|  | %1 = load i32, i32* %b.addr, align 4 | 
|  | %add = add nsw i32 %0, %1 | 
|  | ret i32 %add | 
|  | } | 
|  |  | 
|  | ; CHECK-LABEL: @iadd_optimize | 
|  | ; CHECK-NOT: alloca | 
|  | ; CHECK-NOT: store | 
|  | ; CHECK-NOT: load | 
|  | ; CHECK: ret | 
|  |  | 
|  | define i32 @iadd_optnone(i32 %a, i32 %b) #1 { | 
|  | entry: | 
|  | %a.addr = alloca i32, align 4 | 
|  | %b.addr = alloca i32, align 4 | 
|  | store i32 %a, i32* %a.addr, align 4 | 
|  | store i32 %b, i32* %b.addr, align 4 | 
|  | %0 = load i32, i32* %a.addr, align 4 | 
|  | %1 = load i32, i32* %b.addr, align 4 | 
|  | %add = add nsw i32 %0, %1 | 
|  | ret i32 %add | 
|  | } | 
|  |  | 
|  | ; CHECK-LABEL: @iadd_optnone | 
|  | ; CHECK: alloca i32 | 
|  | ; CHECK: alloca i32 | 
|  | ; CHECK: store i32 | 
|  | ; CHECK: store i32 | 
|  | ; CHECK: load i32 | 
|  | ; CHECK: load i32 | 
|  | ; CHECK: add nsw i32 | 
|  | ; CHECK: ret i32 | 
|  |  | 
|  | ; float fsub(float a, float b){ return a - b; } | 
|  |  | 
|  | define float @fsub_optimize(float %a, float %b) #0 { | 
|  | entry: | 
|  | %a.addr = alloca float, align 4 | 
|  | %b.addr = alloca float, align 4 | 
|  | store float %a, float* %a.addr, align 4 | 
|  | store float %b, float* %b.addr, align 4 | 
|  | %0 = load float, float* %a.addr, align 4 | 
|  | %1 = load float, float* %b.addr, align 4 | 
|  | %sub = fsub float %0, %1 | 
|  | ret float %sub | 
|  | } | 
|  |  | 
|  | ; CHECK-LABEL: @fsub_optimize | 
|  | ; CHECK-NOT: alloca | 
|  | ; CHECK-NOT: store | 
|  | ; CHECK-NOT: load | 
|  | ; CHECK: ret | 
|  |  | 
|  | define float @fsub_optnone(float %a, float %b) #1 { | 
|  | entry: | 
|  | %a.addr = alloca float, align 4 | 
|  | %b.addr = alloca float, align 4 | 
|  | store float %a, float* %a.addr, align 4 | 
|  | store float %b, float* %b.addr, align 4 | 
|  | %0 = load float, float* %a.addr, align 4 | 
|  | %1 = load float, float* %b.addr, align 4 | 
|  | %sub = fsub float %0, %1 | 
|  | ret float %sub | 
|  | } | 
|  |  | 
|  | ; CHECK-LABEL: @fsub_optnone | 
|  | ; CHECK: alloca float | 
|  | ; CHECK: alloca float | 
|  | ; CHECK: store float | 
|  | ; CHECK: store float | 
|  | ; CHECK: load float | 
|  | ; CHECK: load float | 
|  | ; CHECK: fsub float | 
|  | ; CHECK: ret float | 
|  |  | 
|  | ; typedef float __attribute__((ext_vector_type(4))) float4; | 
|  | ; float4 vmul(float4 a, float4 b){ return a * b; } | 
|  |  | 
|  | define <4 x float> @vmul_optimize(<4 x float> %a, <4 x float> %b) #0 { | 
|  | entry: | 
|  | %a.addr = alloca <4 x float>, align 16 | 
|  | %b.addr = alloca <4 x float>, align 16 | 
|  | store <4 x float> %a, <4 x float>* %a.addr, align 16 | 
|  | store <4 x float> %b, <4 x float>* %b.addr, align 16 | 
|  | %0 = load <4 x float>, <4 x float>* %a.addr, align 16 | 
|  | %1 = load <4 x float>, <4 x float>* %b.addr, align 16 | 
|  | %mul = fmul <4 x float> %0, %1 | 
|  | ret <4 x float> %mul | 
|  | } | 
|  |  | 
|  | ; CHECK-LABEL: @vmul_optimize | 
|  | ; CHECK-NOT: alloca | 
|  | ; CHECK-NOT: store | 
|  | ; CHECK-NOT: load | 
|  | ; CHECK: ret | 
|  |  | 
|  | define <4 x float> @vmul_optnone(<4 x float> %a, <4 x float> %b) #1 { | 
|  | entry: | 
|  | %a.addr = alloca <4 x float>, align 16 | 
|  | %b.addr = alloca <4 x float>, align 16 | 
|  | store <4 x float> %a, <4 x float>* %a.addr, align 16 | 
|  | store <4 x float> %b, <4 x float>* %b.addr, align 16 | 
|  | %0 = load <4 x float>, <4 x float>* %a.addr, align 16 | 
|  | %1 = load <4 x float>, <4 x float>* %b.addr, align 16 | 
|  | %mul = fmul <4 x float> %0, %1 | 
|  | ret <4 x float> %mul | 
|  | } | 
|  |  | 
|  | ; CHECK-LABEL: @vmul_optnone | 
|  | ; CHECK: alloca <4 x float> | 
|  | ; CHECK: alloca <4 x float> | 
|  | ; CHECK: store <4 x float> | 
|  | ; CHECK: store <4 x float> | 
|  | ; CHECK: load <4 x float> | 
|  | ; CHECK: load <4 x float> | 
|  | ; CHECK: fmul <4 x float> | 
|  | ; CHECK: ret |