1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; 3*9880d681SAndroid Build Coastguard Worker; Generated with clang -O2 -S -emit-llvm 4*9880d681SAndroid Build Coastguard Worker; 5*9880d681SAndroid Build Coastguard Worker; /* Test 1 */ 6*9880d681SAndroid Build Coastguard Worker; extern "C" bool bar (long double); 7*9880d681SAndroid Build Coastguard Worker; __attribute__((optnone)) 8*9880d681SAndroid Build Coastguard Worker; extern "C" bool foo(long double x, long double y) 9*9880d681SAndroid Build Coastguard Worker; { 10*9880d681SAndroid Build Coastguard Worker; return (x == y) || (bar(x)); 11*9880d681SAndroid Build Coastguard Worker; } 12*9880d681SAndroid Build Coastguard Worker; 13*9880d681SAndroid Build Coastguard Worker; /* Test 2 */ 14*9880d681SAndroid Build Coastguard Worker; struct FVector { 15*9880d681SAndroid Build Coastguard Worker; float x, y, z; 16*9880d681SAndroid Build Coastguard Worker; inline __attribute__((always_inline)) FVector(float f): x(f), y(f), z(f) {} 17*9880d681SAndroid Build Coastguard Worker; inline __attribute__((always_inline)) FVector func(float p) const 18*9880d681SAndroid Build Coastguard Worker; { 19*9880d681SAndroid Build Coastguard Worker; if( x == 1.f ) { 20*9880d681SAndroid Build Coastguard Worker; return *this; 21*9880d681SAndroid Build Coastguard Worker; } else if( x < p ) { 22*9880d681SAndroid Build Coastguard Worker; return FVector(0.f); 23*9880d681SAndroid Build Coastguard Worker; } 24*9880d681SAndroid Build Coastguard Worker; return FVector(x); 25*9880d681SAndroid Build Coastguard Worker; } 26*9880d681SAndroid Build Coastguard Worker; }; 27*9880d681SAndroid Build Coastguard Worker; 28*9880d681SAndroid Build Coastguard Worker; __attribute__((optnone)) 29*9880d681SAndroid Build Coastguard Worker; int main() 30*9880d681SAndroid Build Coastguard Worker; { 31*9880d681SAndroid Build Coastguard Worker; FVector v(1.0); 32*9880d681SAndroid Build Coastguard Worker; v = v.func(1.e-8); 33*9880d681SAndroid Build Coastguard Worker; return 0; 34*9880d681SAndroid Build Coastguard Worker; } 35*9880d681SAndroid Build Coastguard Worker; 36*9880d681SAndroid Build Coastguard Worker; ModuleID = 'test.cpp' 37*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 38*9880d681SAndroid Build Coastguard Workertarget triple = "x86_64-unknown-linux-gnu" 39*9880d681SAndroid Build Coastguard Worker 40*9880d681SAndroid Build Coastguard Worker%struct.FVector = type { float, float, float } 41*9880d681SAndroid Build Coastguard Worker 42*9880d681SAndroid Build Coastguard Workerdefine zeroext i1 @foo(x86_fp80 %x, x86_fp80 %y) noinline optnone { 43*9880d681SAndroid Build Coastguard Workerentry: 44*9880d681SAndroid Build Coastguard Worker %x.addr = alloca x86_fp80, align 16 45*9880d681SAndroid Build Coastguard Worker %y.addr = alloca x86_fp80, align 16 46*9880d681SAndroid Build Coastguard Worker store x86_fp80 %x, x86_fp80* %x.addr, align 16 47*9880d681SAndroid Build Coastguard Worker store x86_fp80 %y, x86_fp80* %y.addr, align 16 48*9880d681SAndroid Build Coastguard Worker %0 = load x86_fp80, x86_fp80* %x.addr, align 16 49*9880d681SAndroid Build Coastguard Worker %1 = load x86_fp80, x86_fp80* %y.addr, align 16 50*9880d681SAndroid Build Coastguard Worker %cmp = fcmp oeq x86_fp80 %0, %1 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Worker; Test 1 53*9880d681SAndroid Build Coastguard Worker; Make sure that there is no dead code generated 54*9880d681SAndroid Build Coastguard Worker; from Fast-ISel Phi-node handling. We should only 55*9880d681SAndroid Build Coastguard Worker; see one movb of the constant 1, feeding the PHI 56*9880d681SAndroid Build Coastguard Worker; node in lor.end. This covers the code path with 57*9880d681SAndroid Build Coastguard Worker; handlePHINodesInSuccessorBlocks() returning true. 58*9880d681SAndroid Build Coastguard Worker; 59*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo: 60*9880d681SAndroid Build Coastguard Worker; CHECK: movb $1, 61*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: movb $1, 62*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: .LBB0_1: 63*9880d681SAndroid Build Coastguard Worker 64*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %lor.end, label %lor.rhs 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Workerlor.rhs: ; preds = %entry 67*9880d681SAndroid Build Coastguard Worker %2 = load x86_fp80, x86_fp80* %x.addr, align 16 68*9880d681SAndroid Build Coastguard Worker %call = call zeroext i1 @bar(x86_fp80 %2) 69*9880d681SAndroid Build Coastguard Worker br label %lor.end 70*9880d681SAndroid Build Coastguard Worker 71*9880d681SAndroid Build Coastguard Workerlor.end: ; preds = %lor.rhs, %entry 72*9880d681SAndroid Build Coastguard Worker %3 = phi i1 [ true, %entry ], [ %call, %lor.rhs ] 73*9880d681SAndroid Build Coastguard Worker ret i1 %3 74*9880d681SAndroid Build Coastguard Worker} 75*9880d681SAndroid Build Coastguard Worker 76*9880d681SAndroid Build Coastguard Workerdeclare zeroext i1 @bar(x86_fp80) 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Workerdefine i32 @main() noinline optnone { 79*9880d681SAndroid Build Coastguard Workerentry: 80*9880d681SAndroid Build Coastguard Worker %retval = alloca i32, align 4 81*9880d681SAndroid Build Coastguard Worker %v = alloca %struct.FVector, align 4 82*9880d681SAndroid Build Coastguard Worker %ref.tmp = alloca %struct.FVector, align 4 83*9880d681SAndroid Build Coastguard Worker %tmp = alloca { <2 x float>, float }, align 8 84*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %retval, align 4 85*9880d681SAndroid Build Coastguard Worker %0 = bitcast %struct.FVector* %v to i8* 86*9880d681SAndroid Build Coastguard Worker call void @llvm.lifetime.start(i64 12, i8* %0) nounwind 87*9880d681SAndroid Build Coastguard Worker %x.i = getelementptr inbounds %struct.FVector, %struct.FVector* %v, i64 0, i32 0 88*9880d681SAndroid Build Coastguard Worker store float 1.000000e+00, float* %x.i, align 4 89*9880d681SAndroid Build Coastguard Worker %y.i = getelementptr inbounds %struct.FVector, %struct.FVector* %v, i64 0, i32 1 90*9880d681SAndroid Build Coastguard Worker store float 1.000000e+00, float* %y.i, align 4 91*9880d681SAndroid Build Coastguard Worker %z.i = getelementptr inbounds %struct.FVector, %struct.FVector* %v, i64 0, i32 2 92*9880d681SAndroid Build Coastguard Worker store float 1.000000e+00, float* %z.i, align 4 93*9880d681SAndroid Build Coastguard Worker %x.i.1 = getelementptr inbounds %struct.FVector, %struct.FVector* %v, i64 0, i32 0 94*9880d681SAndroid Build Coastguard Worker %1 = load float, float* %x.i.1, align 4 95*9880d681SAndroid Build Coastguard Worker %cmp.i = fcmp oeq float %1, 1.000000e+00 96*9880d681SAndroid Build Coastguard Worker br i1 %cmp.i, label %if.then.i, label %if.else.i 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard Workerif.then.i: ; preds = %entry 99*9880d681SAndroid Build Coastguard Worker %retval.sroa.0.0..sroa_cast.i = bitcast %struct.FVector* %v to <2 x float>* 100*9880d681SAndroid Build Coastguard Worker %retval.sroa.0.0.copyload.i = load <2 x float>, <2 x float>* %retval.sroa.0.0..sroa_cast.i, align 4 101*9880d681SAndroid Build Coastguard Worker %retval.sroa.6.0..sroa_idx16.i = getelementptr inbounds %struct.FVector, %struct.FVector* %v, i64 0, i32 2 102*9880d681SAndroid Build Coastguard Worker %retval.sroa.6.0.copyload.i = load float, float* %retval.sroa.6.0..sroa_idx16.i, align 4 103*9880d681SAndroid Build Coastguard Worker br label %func.exit 104*9880d681SAndroid Build Coastguard Worker 105*9880d681SAndroid Build Coastguard Workerif.else.i: ; preds = %entry 106*9880d681SAndroid Build Coastguard Worker 107*9880d681SAndroid Build Coastguard Worker; Test 2 108*9880d681SAndroid Build Coastguard Worker; In order to feed the first PHI node in func.exit handlePHINodesInSuccessorBlocks() 109*9880d681SAndroid Build Coastguard Worker; generates a local value instruction, but it cannot handle the second PHI node and 110*9880d681SAndroid Build Coastguard Worker; returns false to let SelectionDAGISel handle both cases. Make sure the generated 111*9880d681SAndroid Build Coastguard Worker; local value instruction is removed. 112*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: main: 113*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: .LBB1_2: 114*9880d681SAndroid Build Coastguard Worker; CHECK: xorps [[REG:%xmm[0-7]]], [[REG]] 115*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: xorps [[REG]], [[REG]] 116*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: .LBB1_3: 117*9880d681SAndroid Build Coastguard Worker 118*9880d681SAndroid Build Coastguard Worker %cmp3.i = fcmp olt float %1, 0x3E45798EE0000000 119*9880d681SAndroid Build Coastguard Worker br i1 %cmp3.i, label %func.exit, label %if.end.5.i 120*9880d681SAndroid Build Coastguard Worker 121*9880d681SAndroid Build Coastguard Workerif.end.5.i: ; preds = %if.else.i 122*9880d681SAndroid Build Coastguard Worker %retval.sroa.0.0.vec.insert13.i = insertelement <2 x float> undef, float %1, i32 0 123*9880d681SAndroid Build Coastguard Worker %retval.sroa.0.4.vec.insert15.i = insertelement <2 x float> %retval.sroa.0.0.vec.insert13.i, float %1, i32 1 124*9880d681SAndroid Build Coastguard Worker br label %func.exit 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Workerfunc.exit: ; preds = %if.then.i, %if.else.i, %if.end.5.i 127*9880d681SAndroid Build Coastguard Worker %retval.sroa.6.0.i = phi float [ %retval.sroa.6.0.copyload.i, %if.then.i ], [ %1, %if.end.5.i ], [ 0.000000e+00, %if.else.i ] 128*9880d681SAndroid Build Coastguard Worker %retval.sroa.0.0.i = phi <2 x float> [ %retval.sroa.0.0.copyload.i, %if.then.i ], [ %retval.sroa.0.4.vec.insert15.i, %if.end.5.i ], [ zeroinitializer, %if.else.i ] 129*9880d681SAndroid Build Coastguard Worker %.fca.0.insert.i = insertvalue { <2 x float>, float } undef, <2 x float> %retval.sroa.0.0.i, 0 130*9880d681SAndroid Build Coastguard Worker %.fca.1.insert.i = insertvalue { <2 x float>, float } %.fca.0.insert.i, float %retval.sroa.6.0.i, 1 131*9880d681SAndroid Build Coastguard Worker store { <2 x float>, float } %.fca.1.insert.i, { <2 x float>, float }* %tmp, align 8 132*9880d681SAndroid Build Coastguard Worker %2 = bitcast { <2 x float>, float }* %tmp to i8* 133*9880d681SAndroid Build Coastguard Worker %3 = bitcast %struct.FVector* %ref.tmp to i8* 134*9880d681SAndroid Build Coastguard Worker call void @llvm.memcpy.p0i8.p0i8.i64(i8* %3, i8* %2, i64 12, i32 4, i1 false) 135*9880d681SAndroid Build Coastguard Worker %4 = bitcast %struct.FVector* %v to i8* 136*9880d681SAndroid Build Coastguard Worker %5 = bitcast %struct.FVector* %ref.tmp to i8* 137*9880d681SAndroid Build Coastguard Worker call void @llvm.memcpy.p0i8.p0i8.i64(i8* %4, i8* %5, i64 12, i32 4, i1 false) 138*9880d681SAndroid Build Coastguard Worker %6 = bitcast %struct.FVector* %v to i8* 139*9880d681SAndroid Build Coastguard Worker call void @llvm.lifetime.end(i64 12, i8* %6) nounwind 140*9880d681SAndroid Build Coastguard Worker ret i32 0 141*9880d681SAndroid Build Coastguard Worker} 142*9880d681SAndroid Build Coastguard Worker 143*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.lifetime.start(i64, i8* nocapture) argmemonly nounwind 144*9880d681SAndroid Build Coastguard Worker 145*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1) argmemonly nounwind 146*9880d681SAndroid Build Coastguard Worker 147*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.lifetime.end(i64, i8* nocapture) argmemonly nounwind 148