1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -basic-aa -slp-vectorizer -dce -S -mtriple=x86_64-apple-macosx10.8.0 -mcpu=corei7-avx | FileCheck %s 3 4;int foo(char * restrict A, float * restrict B, float T) { 5; A[0] = (T * B[10] + 4.0); 6; A[1] = (T * B[11] + 5.0); 7; A[2] = (T * B[12] + 6.0); 8;} 9 10define i32 @foo(i8* noalias nocapture %A, float* noalias nocapture %B, float %T) { 11; CHECK-LABEL: @foo( 12; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds float, float* [[B:%.*]], i64 10 13; CHECK-NEXT: [[TMP2:%.*]] = load float, float* [[TMP1]], align 4 14; CHECK-NEXT: [[TMP3:%.*]] = fmul float [[TMP2]], [[T:%.*]] 15; CHECK-NEXT: [[TMP4:%.*]] = fpext float [[TMP3]] to double 16; CHECK-NEXT: [[TMP5:%.*]] = fadd double [[TMP4]], 4.000000e+00 17; CHECK-NEXT: [[TMP6:%.*]] = fptosi double [[TMP5]] to i8 18; CHECK-NEXT: store i8 [[TMP6]], i8* [[A:%.*]], align 1 19; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds float, float* [[B]], i64 11 20; CHECK-NEXT: [[TMP8:%.*]] = load float, float* [[TMP7]], align 4 21; CHECK-NEXT: [[TMP9:%.*]] = fmul float [[TMP8]], [[T]] 22; CHECK-NEXT: [[TMP10:%.*]] = fpext float [[TMP9]] to double 23; CHECK-NEXT: [[TMP11:%.*]] = fadd double [[TMP10]], 5.000000e+00 24; CHECK-NEXT: [[TMP12:%.*]] = fptosi double [[TMP11]] to i8 25; CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 1 26; CHECK-NEXT: store i8 [[TMP12]], i8* [[TMP13]], align 1 27; CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds float, float* [[B]], i64 12 28; CHECK-NEXT: [[TMP15:%.*]] = load float, float* [[TMP14]], align 4 29; CHECK-NEXT: [[TMP16:%.*]] = fmul float [[TMP15]], [[T]] 30; CHECK-NEXT: [[TMP17:%.*]] = fpext float [[TMP16]] to double 31; CHECK-NEXT: [[TMP18:%.*]] = fadd double [[TMP17]], 6.000000e+00 32; CHECK-NEXT: [[TMP19:%.*]] = fptosi double [[TMP18]] to i8 33; CHECK-NEXT: [[TMP20:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 2 34; CHECK-NEXT: store i8 [[TMP19]], i8* [[TMP20]], align 1 35; CHECK-NEXT: ret i32 undef 36; 37 %1 = getelementptr inbounds float, float* %B, i64 10 38 %2 = load float, float* %1, align 4 39 %3 = fmul float %2, %T 40 %4 = fpext float %3 to double 41 %5 = fadd double %4, 4.000000e+00 42 %6 = fptosi double %5 to i8 43 store i8 %6, i8* %A, align 1 44 %7 = getelementptr inbounds float, float* %B, i64 11 45 %8 = load float, float* %7, align 4 46 %9 = fmul float %8, %T 47 %10 = fpext float %9 to double 48 %11 = fadd double %10, 5.000000e+00 49 %12 = fptosi double %11 to i8 50 %13 = getelementptr inbounds i8, i8* %A, i64 1 51 store i8 %12, i8* %13, align 1 52 %14 = getelementptr inbounds float, float* %B, i64 12 53 %15 = load float, float* %14, align 4 54 %16 = fmul float %15, %T 55 %17 = fpext float %16 to double 56 %18 = fadd double %17, 6.000000e+00 57 %19 = fptosi double %18 to i8 58 %20 = getelementptr inbounds i8, i8* %A, i64 2 59 store i8 %19, i8* %20, align 1 60 ret i32 undef 61} 62 63; PR41892 64define void @test_v4f32_v2f32_store(<4 x float> %f, float* %p){ 65; CHECK-LABEL: @test_v4f32_v2f32_store( 66; CHECK-NEXT: [[X0:%.*]] = extractelement <4 x float> [[F:%.*]], i64 0 67; CHECK-NEXT: [[X1:%.*]] = extractelement <4 x float> [[F]], i64 1 68; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x float> poison, float [[X0]], i32 0 69; CHECK-NEXT: [[TMP2:%.*]] = insertelement <2 x float> [[TMP1]], float [[X1]], i32 1 70; CHECK-NEXT: [[TMP3:%.*]] = bitcast float* [[P:%.*]] to <2 x float>* 71; CHECK-NEXT: store <2 x float> [[TMP2]], <2 x float>* [[TMP3]], align 4 72; CHECK-NEXT: ret void 73; 74 %x0 = extractelement <4 x float> %f, i64 0 75 %x1 = extractelement <4 x float> %f, i64 1 76 %p1 = getelementptr inbounds float, float* %p, i64 1 77 store float %x0, float* %p, align 4 78 store float %x1, float* %p1, align 4 79 ret void 80} 81 82define void @test_v4f32_v2f32_splat_store(<4 x float> %f, float* %p){ 83; CHECK-LABEL: @test_v4f32_v2f32_splat_store( 84; CHECK-NEXT: [[X0:%.*]] = extractelement <4 x float> [[F:%.*]], i64 0 85; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds float, float* [[P:%.*]], i64 1 86; CHECK-NEXT: store float [[X0]], float* [[P]], align 4 87; CHECK-NEXT: store float [[X0]], float* [[P1]], align 4 88; CHECK-NEXT: ret void 89; 90 %x0 = extractelement <4 x float> %f, i64 0 91 %p1 = getelementptr inbounds float, float* %p, i64 1 92 store float %x0, float* %p, align 4 93 store float %x0, float* %p1, align 4 94 ret void 95} 96 97define void @test_v4f32_v3f32_store(<4 x float> %f, float* %p){ 98; CHECK-LABEL: @test_v4f32_v3f32_store( 99; CHECK-NEXT: [[X0:%.*]] = extractelement <4 x float> [[F:%.*]], i64 0 100; CHECK-NEXT: [[X1:%.*]] = extractelement <4 x float> [[F]], i64 1 101; CHECK-NEXT: [[X2:%.*]] = extractelement <4 x float> [[F]], i64 2 102; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds float, float* [[P:%.*]], i64 2 103; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x float> poison, float [[X0]], i32 0 104; CHECK-NEXT: [[TMP2:%.*]] = insertelement <2 x float> [[TMP1]], float [[X1]], i32 1 105; CHECK-NEXT: [[TMP3:%.*]] = bitcast float* [[P]] to <2 x float>* 106; CHECK-NEXT: store <2 x float> [[TMP2]], <2 x float>* [[TMP3]], align 4 107; CHECK-NEXT: store float [[X2]], float* [[P2]], align 4 108; CHECK-NEXT: ret void 109; 110 %x0 = extractelement <4 x float> %f, i64 0 111 %x1 = extractelement <4 x float> %f, i64 1 112 %x2 = extractelement <4 x float> %f, i64 2 113 %p1 = getelementptr inbounds float, float* %p, i64 1 114 %p2 = getelementptr inbounds float, float* %p, i64 2 115 store float %x0, float* %p, align 4 116 store float %x1, float* %p1, align 4 117 store float %x2, float* %p2, align 4 118 ret void 119} 120 121define void @test_v4f32_v3f32_splat_store(<4 x float> %f, float* %p){ 122; CHECK-LABEL: @test_v4f32_v3f32_splat_store( 123; CHECK-NEXT: [[X0:%.*]] = extractelement <4 x float> [[F:%.*]], i64 0 124; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds float, float* [[P:%.*]], i64 1 125; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds float, float* [[P]], i64 2 126; CHECK-NEXT: store float [[X0]], float* [[P]], align 4 127; CHECK-NEXT: store float [[X0]], float* [[P1]], align 4 128; CHECK-NEXT: store float [[X0]], float* [[P2]], align 4 129; CHECK-NEXT: ret void 130; 131 %x0 = extractelement <4 x float> %f, i64 0 132 %p1 = getelementptr inbounds float, float* %p, i64 1 133 %p2 = getelementptr inbounds float, float* %p, i64 2 134 store float %x0, float* %p, align 4 135 store float %x0, float* %p1, align 4 136 store float %x0, float* %p2, align 4 137 ret void 138} 139 140define void @test_v4f32_v4f32_store(<4 x float> %f, float* %p){ 141; CHECK-LABEL: @test_v4f32_v4f32_store( 142; CHECK-NEXT: [[TMP1:%.*]] = bitcast float* [[P:%.*]] to <4 x float>* 143; CHECK-NEXT: store <4 x float> [[F:%.*]], <4 x float>* [[TMP1]], align 4 144; CHECK-NEXT: ret void 145; 146 %x0 = extractelement <4 x float> %f, i64 0 147 %x1 = extractelement <4 x float> %f, i64 1 148 %x2 = extractelement <4 x float> %f, i64 2 149 %x3 = extractelement <4 x float> %f, i64 3 150 %p1 = getelementptr inbounds float, float* %p, i64 1 151 %p2 = getelementptr inbounds float, float* %p, i64 2 152 %p3 = getelementptr inbounds float, float* %p, i64 3 153 store float %x0, float* %p, align 4 154 store float %x1, float* %p1, align 4 155 store float %x2, float* %p2, align 4 156 store float %x3, float* %p3, align 4 157 ret void 158} 159 160define void @test_v4f32_v4f32_splat_store(<4 x float> %f, float* %p){ 161; CHECK-LABEL: @test_v4f32_v4f32_splat_store( 162; CHECK-NEXT: [[X0:%.*]] = extractelement <4 x float> [[F:%.*]], i64 0 163; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x float> poison, float [[X0]], i32 0 164; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x float> [[TMP1]], <4 x float> poison, <4 x i32> zeroinitializer 165; CHECK-NEXT: [[TMP2:%.*]] = bitcast float* [[P:%.*]] to <4 x float>* 166; CHECK-NEXT: store <4 x float> [[SHUFFLE]], <4 x float>* [[TMP2]], align 4 167; CHECK-NEXT: ret void 168; 169 %x0 = extractelement <4 x float> %f, i64 0 170 %p1 = getelementptr inbounds float, float* %p, i64 1 171 %p2 = getelementptr inbounds float, float* %p, i64 2 172 %p3 = getelementptr inbounds float, float* %p, i64 3 173 store float %x0, float* %p, align 4 174 store float %x0, float* %p1, align 4 175 store float %x0, float* %p2, align 4 176 store float %x0, float* %p3, align 4 177 ret void 178} 179