1*9880d681SAndroid Build Coastguard Worker; RUN: opt -codegenprepare -mtriple=thumbv7-apple-ios %s -o - -mattr=+neon -S | FileCheck --check-prefix=IR-BOTH --check-prefix=IR-NORMAL %s 2*9880d681SAndroid Build Coastguard Worker; RUN: opt -codegenprepare -mtriple=thumbv7-apple-ios %s -o - -mattr=+neon -S -stress-cgp-store-extract | FileCheck --check-prefix=IR-BOTH --check-prefix=IR-STRESS %s 3*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=thumbv7-apple-ios %s -o - -mattr=+neon | FileCheck --check-prefix=ASM %s 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @simpleOneInstructionPromotion 6*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1 7*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[VECTOR_OR:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[LOAD]], <i32 undef, i32 1> 8*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[VECTOR_OR]], i32 1 9*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[EXTRACT]], i32* %dest 10*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret 11*9880d681SAndroid Build Coastguard Worker; 12*9880d681SAndroid Build Coastguard Worker; Make sure we got rid of any expensive vmov.32 instructions. 13*9880d681SAndroid Build Coastguard Worker; ASM-LABEL: simpleOneInstructionPromotion: 14*9880d681SAndroid Build Coastguard Worker; ASM: vldr [[LOAD:d[0-9]+]], [r0] 15*9880d681SAndroid Build Coastguard Worker; ASM-NEXT: vorr.i32 [[LOAD]], #0x1 16*9880d681SAndroid Build Coastguard Worker; ASM-NEXT: vst1.32 {[[LOAD]][1]}, [r1:32] 17*9880d681SAndroid Build Coastguard Worker; ASM-NEXT: bx 18*9880d681SAndroid Build Coastguard Workerdefine void @simpleOneInstructionPromotion(<2 x i32>* %addr1, i32* %dest) { 19*9880d681SAndroid Build Coastguard Worker %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8 20*9880d681SAndroid Build Coastguard Worker %extract = extractelement <2 x i32> %in1, i32 1 21*9880d681SAndroid Build Coastguard Worker %out = or i32 %extract, 1 22*9880d681SAndroid Build Coastguard Worker store i32 %out, i32* %dest, align 4 23*9880d681SAndroid Build Coastguard Worker ret void 24*9880d681SAndroid Build Coastguard Worker} 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @unsupportedInstructionForPromotion 27*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1 28*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 0 29*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[CMP:%[a-zA-Z_0-9-]+]] = icmp eq i32 [[EXTRACT]], %in2 30*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i1 [[CMP]], i1* %dest 31*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret 32*9880d681SAndroid Build Coastguard Worker; 33*9880d681SAndroid Build Coastguard Worker; ASM-LABEL: unsupportedInstructionForPromotion: 34*9880d681SAndroid Build Coastguard Worker; ASM: vldr [[LOAD:d[0-9]+]], [r0] 35*9880d681SAndroid Build Coastguard Worker; ASM: vmov.32 {{r[0-9]+}}, [[LOAD]] 36*9880d681SAndroid Build Coastguard Worker; ASM: bx 37*9880d681SAndroid Build Coastguard Workerdefine void @unsupportedInstructionForPromotion(<2 x i32>* %addr1, i32 %in2, i1* %dest) { 38*9880d681SAndroid Build Coastguard Worker %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8 39*9880d681SAndroid Build Coastguard Worker %extract = extractelement <2 x i32> %in1, i32 0 40*9880d681SAndroid Build Coastguard Worker %out = icmp eq i32 %extract, %in2 41*9880d681SAndroid Build Coastguard Worker store i1 %out, i1* %dest, align 4 42*9880d681SAndroid Build Coastguard Worker ret void 43*9880d681SAndroid Build Coastguard Worker} 44*9880d681SAndroid Build Coastguard Worker 45*9880d681SAndroid Build Coastguard Worker 46*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @unsupportedChainInDifferentBBs 47*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1 48*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 0 49*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: br i1 %bool, label %bb2, label %end 50*9880d681SAndroid Build Coastguard Worker; BB2 51*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[OR:%[a-zA-Z_0-9-]+]] = or i32 [[EXTRACT]], 1 52*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[OR]], i32* %dest, align 4 53*9880d681SAndroid Build Coastguard Worker; IR-BOTH: ret 54*9880d681SAndroid Build Coastguard Worker; 55*9880d681SAndroid Build Coastguard Worker; ASM-LABEL: unsupportedChainInDifferentBBs: 56*9880d681SAndroid Build Coastguard Worker; ASM: vldrne [[LOAD:d[0-9]+]], [r0] 57*9880d681SAndroid Build Coastguard Worker; ASM: vmovne.32 {{r[0-9]+}}, [[LOAD]] 58*9880d681SAndroid Build Coastguard Worker; ASM: bx 59*9880d681SAndroid Build Coastguard Workerdefine void @unsupportedChainInDifferentBBs(<2 x i32>* %addr1, i32* %dest, i1 %bool) { 60*9880d681SAndroid Build Coastguard Workerbb1: 61*9880d681SAndroid Build Coastguard Worker %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8 62*9880d681SAndroid Build Coastguard Worker %extract = extractelement <2 x i32> %in1, i32 0 63*9880d681SAndroid Build Coastguard Worker br i1 %bool, label %bb2, label %end 64*9880d681SAndroid Build Coastguard Workerbb2: 65*9880d681SAndroid Build Coastguard Worker %out = or i32 %extract, 1 66*9880d681SAndroid Build Coastguard Worker store i32 %out, i32* %dest, align 4 67*9880d681SAndroid Build Coastguard Worker br label %end 68*9880d681SAndroid Build Coastguard Workerend: 69*9880d681SAndroid Build Coastguard Worker ret void 70*9880d681SAndroid Build Coastguard Worker} 71*9880d681SAndroid Build Coastguard Worker 72*9880d681SAndroid Build Coastguard Worker; IR-LABEL: @chainOfInstructionsToPromote 73*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1 74*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[VECTOR_OR1:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[LOAD]], <i32 1, i32 undef> 75*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[VECTOR_OR2:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[VECTOR_OR1]], <i32 1, i32 undef> 76*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[VECTOR_OR3:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[VECTOR_OR2]], <i32 1, i32 undef> 77*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[VECTOR_OR4:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[VECTOR_OR3]], <i32 1, i32 undef> 78*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[VECTOR_OR5:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[VECTOR_OR4]], <i32 1, i32 undef> 79*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[VECTOR_OR6:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[VECTOR_OR5]], <i32 1, i32 undef> 80*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[VECTOR_OR7:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[VECTOR_OR6]], <i32 1, i32 undef> 81*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[VECTOR_OR7]], i32 0 82*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[EXTRACT]], i32* %dest 83*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret 84*9880d681SAndroid Build Coastguard Worker; 85*9880d681SAndroid Build Coastguard Worker; ASM-LABEL: chainOfInstructionsToPromote: 86*9880d681SAndroid Build Coastguard Worker; ASM: vldr [[LOAD:d[0-9]+]], [r0] 87*9880d681SAndroid Build Coastguard Worker; ASM-NOT: vmov.32 {{r[0-9]+}}, [[LOAD]] 88*9880d681SAndroid Build Coastguard Worker; ASM: bx 89*9880d681SAndroid Build Coastguard Workerdefine void @chainOfInstructionsToPromote(<2 x i32>* %addr1, i32* %dest) { 90*9880d681SAndroid Build Coastguard Worker %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8 91*9880d681SAndroid Build Coastguard Worker %extract = extractelement <2 x i32> %in1, i32 0 92*9880d681SAndroid Build Coastguard Worker %out1 = or i32 %extract, 1 93*9880d681SAndroid Build Coastguard Worker %out2 = or i32 %out1, 1 94*9880d681SAndroid Build Coastguard Worker %out3 = or i32 %out2, 1 95*9880d681SAndroid Build Coastguard Worker %out4 = or i32 %out3, 1 96*9880d681SAndroid Build Coastguard Worker %out5 = or i32 %out4, 1 97*9880d681SAndroid Build Coastguard Worker %out6 = or i32 %out5, 1 98*9880d681SAndroid Build Coastguard Worker %out7 = or i32 %out6, 1 99*9880d681SAndroid Build Coastguard Worker store i32 %out7, i32* %dest, align 4 100*9880d681SAndroid Build Coastguard Worker ret void 101*9880d681SAndroid Build Coastguard Worker} 102*9880d681SAndroid Build Coastguard Worker 103*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @unsupportedMultiUses 104*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1 105*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1 106*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[OR:%[a-zA-Z_0-9-]+]] = or i32 [[EXTRACT]], 1 107*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[OR]], i32* %dest 108*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret i32 [[OR]] 109*9880d681SAndroid Build Coastguard Worker; 110*9880d681SAndroid Build Coastguard Worker; ASM-LABEL: unsupportedMultiUses: 111*9880d681SAndroid Build Coastguard Worker; ASM: vldr [[LOAD:d[0-9]+]], [r0] 112*9880d681SAndroid Build Coastguard Worker; ASM: vmov.32 {{r[0-9]+}}, [[LOAD]] 113*9880d681SAndroid Build Coastguard Worker; ASM: bx 114*9880d681SAndroid Build Coastguard Workerdefine i32 @unsupportedMultiUses(<2 x i32>* %addr1, i32* %dest) { 115*9880d681SAndroid Build Coastguard Worker %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8 116*9880d681SAndroid Build Coastguard Worker %extract = extractelement <2 x i32> %in1, i32 1 117*9880d681SAndroid Build Coastguard Worker %out = or i32 %extract, 1 118*9880d681SAndroid Build Coastguard Worker store i32 %out, i32* %dest, align 4 119*9880d681SAndroid Build Coastguard Worker ret i32 %out 120*9880d681SAndroid Build Coastguard Worker} 121*9880d681SAndroid Build Coastguard Worker 122*9880d681SAndroid Build Coastguard Worker; Check that we promote we a splat constant when this is a division. 123*9880d681SAndroid Build Coastguard Worker; The NORMAL mode does not promote anything as divisions are not legal. 124*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @udivCase 125*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1 126*9880d681SAndroid Build Coastguard Worker; Scalar version: 127*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1 128*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = udiv i32 [[EXTRACT]], 7 129*9880d681SAndroid Build Coastguard Worker; Vector version: 130*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = udiv <2 x i32> [[LOAD]], <i32 7, i32 7> 131*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[DIV]], i32 1 132*9880d681SAndroid Build Coastguard Worker; 133*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[RES]], i32* %dest 134*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret 135*9880d681SAndroid Build Coastguard Workerdefine void @udivCase(<2 x i32>* %addr1, i32* %dest) { 136*9880d681SAndroid Build Coastguard Worker %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8 137*9880d681SAndroid Build Coastguard Worker %extract = extractelement <2 x i32> %in1, i32 1 138*9880d681SAndroid Build Coastguard Worker %out = udiv i32 %extract, 7 139*9880d681SAndroid Build Coastguard Worker store i32 %out, i32* %dest, align 4 140*9880d681SAndroid Build Coastguard Worker ret void 141*9880d681SAndroid Build Coastguard Worker} 142*9880d681SAndroid Build Coastguard Worker 143*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @uremCase 144*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1 145*9880d681SAndroid Build Coastguard Worker; Scalar version: 146*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1 147*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = urem i32 [[EXTRACT]], 7 148*9880d681SAndroid Build Coastguard Worker; Vector version: 149*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = urem <2 x i32> [[LOAD]], <i32 7, i32 7> 150*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[DIV]], i32 1 151*9880d681SAndroid Build Coastguard Worker; 152*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[RES]], i32* %dest 153*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret 154*9880d681SAndroid Build Coastguard Workerdefine void @uremCase(<2 x i32>* %addr1, i32* %dest) { 155*9880d681SAndroid Build Coastguard Worker %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8 156*9880d681SAndroid Build Coastguard Worker %extract = extractelement <2 x i32> %in1, i32 1 157*9880d681SAndroid Build Coastguard Worker %out = urem i32 %extract, 7 158*9880d681SAndroid Build Coastguard Worker store i32 %out, i32* %dest, align 4 159*9880d681SAndroid Build Coastguard Worker ret void 160*9880d681SAndroid Build Coastguard Worker} 161*9880d681SAndroid Build Coastguard Worker 162*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @sdivCase 163*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1 164*9880d681SAndroid Build Coastguard Worker; Scalar version: 165*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1 166*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = sdiv i32 [[EXTRACT]], 7 167*9880d681SAndroid Build Coastguard Worker; Vector version: 168*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = sdiv <2 x i32> [[LOAD]], <i32 7, i32 7> 169*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[DIV]], i32 1 170*9880d681SAndroid Build Coastguard Worker; 171*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[RES]], i32* %dest 172*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret 173*9880d681SAndroid Build Coastguard Workerdefine void @sdivCase(<2 x i32>* %addr1, i32* %dest) { 174*9880d681SAndroid Build Coastguard Worker %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8 175*9880d681SAndroid Build Coastguard Worker %extract = extractelement <2 x i32> %in1, i32 1 176*9880d681SAndroid Build Coastguard Worker %out = sdiv i32 %extract, 7 177*9880d681SAndroid Build Coastguard Worker store i32 %out, i32* %dest, align 4 178*9880d681SAndroid Build Coastguard Worker ret void 179*9880d681SAndroid Build Coastguard Worker} 180*9880d681SAndroid Build Coastguard Worker 181*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @sremCase 182*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1 183*9880d681SAndroid Build Coastguard Worker; Scalar version: 184*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1 185*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = srem i32 [[EXTRACT]], 7 186*9880d681SAndroid Build Coastguard Worker; Vector version: 187*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = srem <2 x i32> [[LOAD]], <i32 7, i32 7> 188*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[DIV]], i32 1 189*9880d681SAndroid Build Coastguard Worker; 190*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[RES]], i32* %dest 191*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret 192*9880d681SAndroid Build Coastguard Workerdefine void @sremCase(<2 x i32>* %addr1, i32* %dest) { 193*9880d681SAndroid Build Coastguard Worker %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8 194*9880d681SAndroid Build Coastguard Worker %extract = extractelement <2 x i32> %in1, i32 1 195*9880d681SAndroid Build Coastguard Worker %out = srem i32 %extract, 7 196*9880d681SAndroid Build Coastguard Worker store i32 %out, i32* %dest, align 4 197*9880d681SAndroid Build Coastguard Worker ret void 198*9880d681SAndroid Build Coastguard Worker} 199*9880d681SAndroid Build Coastguard Worker 200*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @fdivCase 201*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x float>, <2 x float>* %addr1 202*9880d681SAndroid Build Coastguard Worker; Scalar version: 203*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[LOAD]], i32 1 204*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = fdiv float [[EXTRACT]], 7.0 205*9880d681SAndroid Build Coastguard Worker; Vector version: 206*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = fdiv <2 x float> [[LOAD]], <float 7.000000e+00, float 7.000000e+00> 207*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[DIV]], i32 1 208*9880d681SAndroid Build Coastguard Worker; 209*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store float [[RES]], float* %dest 210*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret 211*9880d681SAndroid Build Coastguard Workerdefine void @fdivCase(<2 x float>* %addr1, float* %dest) { 212*9880d681SAndroid Build Coastguard Worker %in1 = load <2 x float>, <2 x float>* %addr1, align 8 213*9880d681SAndroid Build Coastguard Worker %extract = extractelement <2 x float> %in1, i32 1 214*9880d681SAndroid Build Coastguard Worker %out = fdiv float %extract, 7.0 215*9880d681SAndroid Build Coastguard Worker store float %out, float* %dest, align 4 216*9880d681SAndroid Build Coastguard Worker ret void 217*9880d681SAndroid Build Coastguard Worker} 218*9880d681SAndroid Build Coastguard Worker 219*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @fremCase 220*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x float>, <2 x float>* %addr1 221*9880d681SAndroid Build Coastguard Worker; Scalar version: 222*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[LOAD]], i32 1 223*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = frem float [[EXTRACT]], 7.0 224*9880d681SAndroid Build Coastguard Worker; Vector version: 225*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = frem <2 x float> [[LOAD]], <float 7.000000e+00, float 7.000000e+00> 226*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[DIV]], i32 1 227*9880d681SAndroid Build Coastguard Worker; 228*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store float [[RES]], float* %dest 229*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret 230*9880d681SAndroid Build Coastguard Workerdefine void @fremCase(<2 x float>* %addr1, float* %dest) { 231*9880d681SAndroid Build Coastguard Worker %in1 = load <2 x float>, <2 x float>* %addr1, align 8 232*9880d681SAndroid Build Coastguard Worker %extract = extractelement <2 x float> %in1, i32 1 233*9880d681SAndroid Build Coastguard Worker %out = frem float %extract, 7.0 234*9880d681SAndroid Build Coastguard Worker store float %out, float* %dest, align 4 235*9880d681SAndroid Build Coastguard Worker ret void 236*9880d681SAndroid Build Coastguard Worker} 237*9880d681SAndroid Build Coastguard Worker 238*9880d681SAndroid Build Coastguard Worker; Check that we do not promote when we may introduce undefined behavior 239*9880d681SAndroid Build Coastguard Worker; like division by zero. 240*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @undefDivCase 241*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1 242*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1 243*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = udiv i32 7, [[EXTRACT]] 244*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[RES]], i32* %dest 245*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret 246*9880d681SAndroid Build Coastguard Workerdefine void @undefDivCase(<2 x i32>* %addr1, i32* %dest) { 247*9880d681SAndroid Build Coastguard Worker %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8 248*9880d681SAndroid Build Coastguard Worker %extract = extractelement <2 x i32> %in1, i32 1 249*9880d681SAndroid Build Coastguard Worker %out = udiv i32 7, %extract 250*9880d681SAndroid Build Coastguard Worker store i32 %out, i32* %dest, align 4 251*9880d681SAndroid Build Coastguard Worker ret void 252*9880d681SAndroid Build Coastguard Worker} 253*9880d681SAndroid Build Coastguard Worker 254*9880d681SAndroid Build Coastguard Worker 255*9880d681SAndroid Build Coastguard Worker; Check that we do not promote when we may introduce undefined behavior 256*9880d681SAndroid Build Coastguard Worker; like division by zero. 257*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @undefRemCase 258*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1 259*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1 260*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = srem i32 7, [[EXTRACT]] 261*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[RES]], i32* %dest 262*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret 263*9880d681SAndroid Build Coastguard Workerdefine void @undefRemCase(<2 x i32>* %addr1, i32* %dest) { 264*9880d681SAndroid Build Coastguard Worker %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8 265*9880d681SAndroid Build Coastguard Worker %extract = extractelement <2 x i32> %in1, i32 1 266*9880d681SAndroid Build Coastguard Worker %out = srem i32 7, %extract 267*9880d681SAndroid Build Coastguard Worker store i32 %out, i32* %dest, align 4 268*9880d681SAndroid Build Coastguard Worker ret void 269*9880d681SAndroid Build Coastguard Worker} 270*9880d681SAndroid Build Coastguard Worker 271*9880d681SAndroid Build Coastguard Worker; Check that we use an undef mask for undefined behavior if the fast-math 272*9880d681SAndroid Build Coastguard Worker; flag is set. 273*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @undefConstantFRemCaseWithFastMath 274*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x float>, <2 x float>* %addr1 275*9880d681SAndroid Build Coastguard Worker; Scalar version: 276*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[LOAD]], i32 1 277*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = frem nnan float [[EXTRACT]], 7.0 278*9880d681SAndroid Build Coastguard Worker; Vector version: 279*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = frem nnan <2 x float> [[LOAD]], <float undef, float 7.000000e+00> 280*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[DIV]], i32 1 281*9880d681SAndroid Build Coastguard Worker; 282*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store float [[RES]], float* %dest 283*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret 284*9880d681SAndroid Build Coastguard Workerdefine void @undefConstantFRemCaseWithFastMath(<2 x float>* %addr1, float* %dest) { 285*9880d681SAndroid Build Coastguard Worker %in1 = load <2 x float>, <2 x float>* %addr1, align 8 286*9880d681SAndroid Build Coastguard Worker %extract = extractelement <2 x float> %in1, i32 1 287*9880d681SAndroid Build Coastguard Worker %out = frem nnan float %extract, 7.0 288*9880d681SAndroid Build Coastguard Worker store float %out, float* %dest, align 4 289*9880d681SAndroid Build Coastguard Worker ret void 290*9880d681SAndroid Build Coastguard Worker} 291*9880d681SAndroid Build Coastguard Worker 292*9880d681SAndroid Build Coastguard Worker; Check that we use an undef mask for undefined behavior if the fast-math 293*9880d681SAndroid Build Coastguard Worker; flag is set. 294*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @undefVectorFRemCaseWithFastMath 295*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x float>, <2 x float>* %addr1 296*9880d681SAndroid Build Coastguard Worker; Scalar version: 297*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[LOAD]], i32 1 298*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = frem nnan float 7.000000e+00, [[EXTRACT]] 299*9880d681SAndroid Build Coastguard Worker; Vector version: 300*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = frem nnan <2 x float> <float undef, float 7.000000e+00>, [[LOAD]] 301*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[DIV]], i32 1 302*9880d681SAndroid Build Coastguard Worker; 303*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store float [[RES]], float* %dest 304*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret 305*9880d681SAndroid Build Coastguard Workerdefine void @undefVectorFRemCaseWithFastMath(<2 x float>* %addr1, float* %dest) { 306*9880d681SAndroid Build Coastguard Worker %in1 = load <2 x float>, <2 x float>* %addr1, align 8 307*9880d681SAndroid Build Coastguard Worker %extract = extractelement <2 x float> %in1, i32 1 308*9880d681SAndroid Build Coastguard Worker %out = frem nnan float 7.0, %extract 309*9880d681SAndroid Build Coastguard Worker store float %out, float* %dest, align 4 310*9880d681SAndroid Build Coastguard Worker ret void 311*9880d681SAndroid Build Coastguard Worker} 312*9880d681SAndroid Build Coastguard Worker 313*9880d681SAndroid Build Coastguard Worker; Check that we are able to promote floating point value. 314*9880d681SAndroid Build Coastguard Worker; This requires the STRESS mode, as floating point value are 315*9880d681SAndroid Build Coastguard Worker; not promote on armv7. 316*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @simpleOneInstructionPromotionFloat 317*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x float>, <2 x float>* %addr1 318*9880d681SAndroid Build Coastguard Worker; Scalar version: 319*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[LOAD]], i32 1 320*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = fadd float [[EXTRACT]], 1.0 321*9880d681SAndroid Build Coastguard Worker; Vector version: 322*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = fadd <2 x float> [[LOAD]], <float undef, float 1.000000e+00> 323*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[DIV]], i32 1 324*9880d681SAndroid Build Coastguard Worker; 325*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store float [[RES]], float* %dest 326*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret 327*9880d681SAndroid Build Coastguard Workerdefine void @simpleOneInstructionPromotionFloat(<2 x float>* %addr1, float* %dest) { 328*9880d681SAndroid Build Coastguard Worker %in1 = load <2 x float>, <2 x float>* %addr1, align 8 329*9880d681SAndroid Build Coastguard Worker %extract = extractelement <2 x float> %in1, i32 1 330*9880d681SAndroid Build Coastguard Worker %out = fadd float %extract, 1.0 331*9880d681SAndroid Build Coastguard Worker store float %out, float* %dest, align 4 332*9880d681SAndroid Build Coastguard Worker ret void 333*9880d681SAndroid Build Coastguard Worker} 334*9880d681SAndroid Build Coastguard Worker 335*9880d681SAndroid Build Coastguard Worker; Check that we correctly use a splat constant when we cannot 336*9880d681SAndroid Build Coastguard Worker; determine at compile time the index of the extract. 337*9880d681SAndroid Build Coastguard Worker; This requires the STRESS modes, as variable index are expensive 338*9880d681SAndroid Build Coastguard Worker; to lower. 339*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @simpleOneInstructionPromotionVariableIdx 340*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1 341*9880d681SAndroid Build Coastguard Worker; Scalar version: 342*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 %idx 343*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = or i32 [[EXTRACT]], 1 344*9880d681SAndroid Build Coastguard Worker; Vector version: 345*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[OR:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[LOAD]], <i32 1, i32 1> 346*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[OR]], i32 %idx 347*9880d681SAndroid Build Coastguard Worker; 348*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[RES]], i32* %dest 349*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret 350*9880d681SAndroid Build Coastguard Workerdefine void @simpleOneInstructionPromotionVariableIdx(<2 x i32>* %addr1, i32* %dest, i32 %idx) { 351*9880d681SAndroid Build Coastguard Worker %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8 352*9880d681SAndroid Build Coastguard Worker %extract = extractelement <2 x i32> %in1, i32 %idx 353*9880d681SAndroid Build Coastguard Worker %out = or i32 %extract, 1 354*9880d681SAndroid Build Coastguard Worker store i32 %out, i32* %dest, align 4 355*9880d681SAndroid Build Coastguard Worker ret void 356*9880d681SAndroid Build Coastguard Worker} 357*9880d681SAndroid Build Coastguard Worker 358*9880d681SAndroid Build Coastguard Worker; Check a vector with more than 2 elements. 359*9880d681SAndroid Build Coastguard Worker; This requires the STRESS mode because currently 'or v8i8' is not marked 360*9880d681SAndroid Build Coastguard Worker; as legal or custom, althought the actual assembly is better if we were 361*9880d681SAndroid Build Coastguard Worker; promoting it. 362*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @simpleOneInstructionPromotion8x8 363*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <8 x i8>, <8 x i8>* %addr1 364*9880d681SAndroid Build Coastguard Worker; Scalar version: 365*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <8 x i8> [[LOAD]], i32 1 366*9880d681SAndroid Build Coastguard Worker; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = or i8 [[EXTRACT]], 1 367*9880d681SAndroid Build Coastguard Worker; Vector version: 368*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[OR:%[a-zA-Z_0-9-]+]] = or <8 x i8> [[LOAD]], <i8 undef, i8 1, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef> 369*9880d681SAndroid Build Coastguard Worker; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <8 x i8> [[OR]], i32 1 370*9880d681SAndroid Build Coastguard Worker; 371*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i8 [[RES]], i8* %dest 372*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret 373*9880d681SAndroid Build Coastguard Workerdefine void @simpleOneInstructionPromotion8x8(<8 x i8>* %addr1, i8* %dest) { 374*9880d681SAndroid Build Coastguard Worker %in1 = load <8 x i8>, <8 x i8>* %addr1, align 8 375*9880d681SAndroid Build Coastguard Worker %extract = extractelement <8 x i8> %in1, i32 1 376*9880d681SAndroid Build Coastguard Worker %out = or i8 %extract, 1 377*9880d681SAndroid Build Coastguard Worker store i8 %out, i8* %dest, align 4 378*9880d681SAndroid Build Coastguard Worker ret void 379*9880d681SAndroid Build Coastguard Worker} 380*9880d681SAndroid Build Coastguard Worker 381*9880d681SAndroid Build Coastguard Worker; Check that we optimized the sequence correctly when it can be 382*9880d681SAndroid Build Coastguard Worker; lowered on a Q register. 383*9880d681SAndroid Build Coastguard Worker; IR-BOTH-LABEL: @simpleOneInstructionPromotion 384*9880d681SAndroid Build Coastguard Worker; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <4 x i32>, <4 x i32>* %addr1 385*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[VECTOR_OR:%[a-zA-Z_0-9-]+]] = or <4 x i32> [[LOAD]], <i32 undef, i32 1, i32 undef, i32 undef> 386*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <4 x i32> [[VECTOR_OR]], i32 1 387*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: store i32 [[EXTRACT]], i32* %dest 388*9880d681SAndroid Build Coastguard Worker; IR-BOTH-NEXT: ret 389*9880d681SAndroid Build Coastguard Worker; 390*9880d681SAndroid Build Coastguard Worker; Make sure we got rid of any expensive vmov.32 instructions. 391*9880d681SAndroid Build Coastguard Worker; ASM-LABEL: simpleOneInstructionPromotion4x32: 392*9880d681SAndroid Build Coastguard Worker; ASM: vld1.64 {[[LOAD:d[0-9]+]], d{{[0-9]+}}}, [r0] 393*9880d681SAndroid Build Coastguard Worker; The Q register used here must be [[LOAD]] / 2, but we cannot express that. 394*9880d681SAndroid Build Coastguard Worker; ASM-NEXT: vorr.i32 q{{[[0-9]+}}, #0x1 395*9880d681SAndroid Build Coastguard Worker; ASM-NEXT: vst1.32 {[[LOAD]][1]}, [r1] 396*9880d681SAndroid Build Coastguard Worker; ASM-NEXT: bx 397*9880d681SAndroid Build Coastguard Workerdefine void @simpleOneInstructionPromotion4x32(<4 x i32>* %addr1, i32* %dest) { 398*9880d681SAndroid Build Coastguard Worker %in1 = load <4 x i32>, <4 x i32>* %addr1, align 8 399*9880d681SAndroid Build Coastguard Worker %extract = extractelement <4 x i32> %in1, i32 1 400*9880d681SAndroid Build Coastguard Worker %out = or i32 %extract, 1 401*9880d681SAndroid Build Coastguard Worker store i32 %out, i32* %dest, align 1 402*9880d681SAndroid Build Coastguard Worker ret void 403*9880d681SAndroid Build Coastguard Worker} 404