| ; 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 |