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