1# RUN: llc --run-pass=register-coalescer -o - %s | FileCheck %s 2# pr45489 3# Coalescing variables across a setjmp call can add a undefined 4# variable value when longjmp if such variables are spilled and 5# altered between the setjmp and longjmp. 6 7# This file tests a very particular case for 8# no coalescing stack pointers across the 9# setjmp call. 10# CHECK: %[[R1:[0-9]+]]:gpr = ADDri %stack.0.P0, 0, 14 11 12# Stack pointer 13# CHECK: %[[R2:[0-9]+]]:gpr = nuw ADDri %[[R1]], 8, 14 14# CHECK: @setjmp 15 16# Not changed between setjmp and bar(longjmp) 17# CHECK-NOT: %{{[0-9]+}}:dpr, %[[R2]]:gpr = VLD1d32wb_fixed %[[R2]], 0, 18# CHECK: BL @_Z3barPx3S37{{.*}} 19# CHECK: %[[R3:[0-9]+]]:gpr = COPY %[[R2]] 20 21# Used after bar 22# CHECK-NOT: VLD1d32wb_fixed %[[R2]] 23# CHECK: VLD1d32wb_fixed %[[R3]] 24--- | 25 target triple = "armv8-arm-none-eabi" 26 27 %"class.std::__1::ios_base::Init" = type { i8 } 28 %struct.S37 = type <{ i8, [7 x i8], %struct.S38, [2 x %"class.std::__1::complex"], float, [4 x i8], i64, i32, [4 x i8] }> 29 %struct.S38 = type { double, i8 } 30 %"class.std::__1::complex" = type { double, double } 31 %struct.S18 = type <{ i32, [4 x i8], double, double, double, i32, [4 x i8], %struct.S23, i32, [4 x i8] }> 32 %struct.S23 = type { [2 x double], half } 33 define i32 @main() { 34 entry: 35 %P0 = alloca %struct.S37, align 8 36 %0 = bitcast ptr %P0 to ptr 37 %jb1 = alloca [20 x i64], align 8 38 %P1 = alloca %struct.S18, align 8 39 %jb2 = alloca [20 x i64], align 8 40 %1 = bitcast ptr %P0 to ptr 41 %M2.i = getelementptr inbounds %struct.S37, ptr %P0, i32 0, i32 2 42 %2 = bitcast ptr %M2.i to ptr 43 call void @llvm.memset.p0.i64(ptr nonnull align 8 dereferenceable(48) %2, i8 0, i64 48, i1 false) 44 %M6.i = getelementptr inbounds %struct.S37, ptr %P0, i32 0, i32 7 45 store i32 0, ptr %M6.i, align 8 46 %3 = bitcast ptr %jb1 to ptr 47 %arraydecay1 = bitcast ptr %jb1 to ptr 48 %call1 = call i32 @setjmp(ptr nonnull %arraydecay1) 49 %tobool = icmp eq i32 %call1, 0 50 br i1 %tobool, label %if.then, label %if.end 51 if.then: ; preds = %entry 52 %4 = bitcast ptr %jb1 to ptr 53 call void (ptr, ptr, ...) @_Z3barPx3S37z(ptr nonnull %4, ptr nonnull byval(%struct.S37) align 8 %P0) 54 unreachable 55 if.end: ; preds = %entry 56 %5 = bitcast ptr %jb1 to ptr 57 %6 = bitcast ptr %P0 to ptr 58 call void asm sideeffect "", "~{r0},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{sp},~{lr}"() 59 %7 = bitcast ptr %0 to ptr 60 %BM0.i = getelementptr inbounds %struct.S18, ptr %0, i32 0, i32 2 61 store double 0.000000e+00, ptr %BM0.i, align 8 62 %M0.i = getelementptr inbounds %struct.S18, ptr %0, i32 0, i32 5 63 store i32 42, ptr %M0.i, align 8 64 %M3.i = getelementptr inbounds %struct.S18, ptr %0, i32 0, i32 7 65 %8 = bitcast ptr %M3.i to ptr 66 call void @llvm.memset.p0.i64(ptr nonnull align 8 dereferenceable(28) %8, i8 0, i64 28, i1 false) 67 %9 = bitcast ptr %jb1 to ptr 68 %arraydecay42 = bitcast ptr %jb1 to ptr 69 %call5 = call i32 @setjmp(ptr nonnull %arraydecay42) 70 %tobool6 = icmp eq i32 %call5, 0 71 br i1 %tobool6, label %if.then7, label %if.end10 72 if.then7: ; preds = %if.end 73 %10 = bitcast ptr %jb1 to ptr 74 call void (ptr, ptr, ...) @_Z3fooPx3S18z(ptr nonnull %10, ptr nonnull byval(%struct.S18) align 8 %0) 75 unreachable 76 if.end10: ; preds = %if.end 77 %11 = bitcast ptr %jb1 to ptr 78 %12 = bitcast ptr %0 to ptr 79 ret i32 0 80 } 81 declare i32 @setjmp(ptr) 82 declare void @_Z3barPx3S37z(ptr, ptr byval(%struct.S37) align 8, ...) 83 declare void @_Z3fooPx3S18z(ptr, ptr byval(%struct.S18) align 8, ...) 84 declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) 85... 86--- 87name: main 88exposesReturnsTwice: true 89frameInfo: 90 adjustsStack: true 91stack: 92 - { id: 0, name: P0, size: 80, alignment: 8, local-offset: -80 } 93 - { id: 1, name: jb1, size: 160, alignment: 8, local-offset: -240 } 94machineFunctionInfo: {} 95body: | 96 bb.0: 97 successors: %bb.1(0x00000001), %bb.4(0x7fffffff) 98 %0:qpr = VMOVv4i32 0, 14, $noreg 99 %1:gpr = ADDri %stack.0.P0, 0, 14, $noreg, $noreg 100 %2:gpr = ADDri %1, 40, 14, $noreg, $noreg 101 VST1q64 %2, 0, %0, 14, $noreg 102 %3:gpr = ADDri %1, 24, 14, $noreg, $noreg 103 VST1q64 killed %3, 0, %0, 14, $noreg 104 %4:gpr = nuw ADDri %1, 8, 14, $noreg, $noreg 105 VST1q64 %4, 0, %0, 14, $noreg 106 %5:gpr = MOVi 0, 14, $noreg, $noreg 107 STRi12 %5, %stack.0.P0, 72, 14, $noreg 108 ADJCALLSTACKDOWN 0, 0, 14, $noreg, implicit-def dead $sp, implicit $sp 109 %6:gpr = ADDri %stack.1.jb1, 0, 14, $noreg, $noreg 110 $r0 = COPY killed %6 111 BL @setjmp, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit killed $r0, implicit-def $sp, implicit-def $r0 112 ADJCALLSTACKUP 0, 0, 14, $noreg, implicit-def dead $sp, implicit $sp 113 %7:gpr = COPY killed $r0 114 CMPri killed %7, 0, 14, $noreg, implicit-def $cpsr 115 Bcc %bb.4, 1, killed $cpsr 116 B %bb.1 117 bb.1: 118 ADJCALLSTACKDOWN 72, 0, 14, $noreg, implicit-def dead $sp, implicit $sp 119 %24:gpr = LDRi12 %stack.0.P0, 0, 14, $noreg 120 %25:gpr = LDRi12 %stack.0.P0, 4, 14, $noreg 121 %27:gpr = COPY $sp 122 %29:gpr = MOVi16 72, 14, $noreg 123 %61:gpr = COPY killed %29 124 %62:gpr = COPY killed %4 125 %63:gpr = COPY killed %27 126 bb.2 (call-frame-size 72): 127 %35:gpr = COPY killed %63 128 %33:gpr = COPY killed %62 129 %31:gpr = COPY killed %61 130 %32:gpr = COPY killed %33 131 %36:dpr, %32:gpr = VLD1d32wb_fixed %32, 0, 14, $noreg 132 %34:gpr = COPY killed %35 133 %34:gpr = VST1d32wb_fixed %34, 0, killed %36, 14, $noreg 134 %30:gpr = SUBri killed %31, 8, 14, $noreg, def $cpsr 135 %61:gpr = COPY killed %30 136 %62:gpr = COPY killed %32 137 %63:gpr = COPY killed %34 138 Bcc %bb.2, 1, killed $cpsr 139 bb.3 (call-frame-size 72): 140 successors: 141 %28:gpr = ADDri %stack.1.jb1, 0, 14, $noreg, $noreg 142 $r0 = COPY killed %28 143 $r2 = COPY killed %24 144 $r3 = COPY killed %25 145 BL @_Z3barPx3S37z, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit killed $r0, implicit killed $r2, implicit killed $r3, implicit-def $sp 146 ADJCALLSTACKUP 72, 0, 14, $noreg, implicit-def dead $sp, implicit $sp 147 bb.4: 148 successors: %bb.5(0x00000001), %bb.6(0x7fffffff) 149 INLINEASM &"", 1, 12, implicit-def dead early-clobber $r0, 12, implicit-def dead early-clobber $r1, 12, implicit-def dead early-clobber $r2, 12, implicit-def dead early-clobber $r3, 12, implicit-def dead early-clobber $r4, 12, implicit-def dead early-clobber $r5, 12, implicit-def dead early-clobber $r6, 12, implicit-def dead early-clobber $r7, 12, implicit-def dead early-clobber $r8, 12, implicit-def dead early-clobber $r9, 12, implicit-def dead early-clobber $r10, 12, implicit-def dead early-clobber $r11, 12, implicit-def dead early-clobber $r12, 12, implicit-def early-clobber $sp, 12, implicit-def dead early-clobber $lr 150 VST1q64 killed %2, 0, %0, 14, $noreg 151 %11:gpr = ADDri killed %1, 52, 14, $noreg, $noreg 152 VST1q32 killed %11, 0, killed %0, 14, $noreg 153 STRi12 %5, %stack.0.P0, 12, 14, $noreg 154 STRi12 killed %5, %stack.0.P0, 8, 14, $noreg 155 %13:gpr = MOVi 42, 14, $noreg, $noreg 156 STRi12 killed %13, %stack.0.P0, 32, 14, $noreg 157 ADJCALLSTACKDOWN 0, 0, 14, $noreg, implicit-def dead $sp, implicit $sp 158 %14:gpr = ADDri %stack.1.jb1, 0, 14, $noreg, $noreg 159 $r0 = COPY killed %14 160 BL @setjmp, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit killed $r0, implicit-def $sp, implicit-def $r0 161 ADJCALLSTACKUP 0, 0, 14, $noreg, implicit-def dead $sp, implicit $sp 162 %15:gpr = COPY killed $r0 163 CMPri killed %15, 0, 14, $noreg, implicit-def $cpsr 164 Bcc %bb.6, 1, killed $cpsr 165 B %bb.5 166 bb.5: 167 successors: 168 ADJCALLSTACKDOWN 64, 0, 14, $noreg, implicit-def dead $sp, implicit $sp 169 %18:gpr = LDRi12 %stack.0.P0, 0, 14, $noreg 170 %19:gpr = LDRi12 %stack.0.P0, 4, 14, $noreg 171 %21:gpr = COPY $sp 172 %37:gpr = COPY killed %4 173 %39:dpr, %37:gpr = VLD1d32wb_fixed %37, 0, 14, $noreg 174 %38:gpr = COPY killed %21 175 %38:gpr = VST1d32wb_fixed %38, 0, killed %39, 14, $noreg 176 %40:gpr = COPY killed %37 177 %42:dpr, %40:gpr = VLD1d32wb_fixed %40, 0, 14, $noreg 178 %41:gpr = COPY killed %38 179 %41:gpr = VST1d32wb_fixed %41, 0, killed %42, 14, $noreg 180 %43:gpr = COPY killed %40 181 %45:dpr, %43:gpr = VLD1d32wb_fixed %43, 0, 14, $noreg 182 %44:gpr = COPY killed %41 183 %44:gpr = VST1d32wb_fixed %44, 0, killed %45, 14, $noreg 184 %46:gpr = COPY killed %43 185 %48:dpr, %46:gpr = VLD1d32wb_fixed %46, 0, 14, $noreg 186 %47:gpr = COPY killed %44 187 %47:gpr = VST1d32wb_fixed %47, 0, killed %48, 14, $noreg 188 %49:gpr = COPY killed %46 189 %51:dpr, %49:gpr = VLD1d32wb_fixed %49, 0, 14, $noreg 190 %50:gpr = COPY killed %47 191 %50:gpr = VST1d32wb_fixed %50, 0, killed %51, 14, $noreg 192 %52:gpr = COPY killed %49 193 %54:dpr, %52:gpr = VLD1d32wb_fixed %52, 0, 14, $noreg 194 %53:gpr = COPY killed %50 195 %53:gpr = VST1d32wb_fixed %53, 0, killed %54, 14, $noreg 196 %55:gpr = COPY killed %52 197 %57:dpr, %55:gpr = VLD1d32wb_fixed %55, 0, 14, $noreg 198 %56:gpr = COPY killed %53 199 %56:gpr = VST1d32wb_fixed %56, 0, killed %57, 14, $noreg 200 %58:gpr = COPY killed %55 201 %60:dpr, dead %58:gpr = VLD1d32wb_fixed %58, 0, 14, $noreg 202 %59:gpr = COPY killed %56 203 dead %59:gpr = VST1d32wb_fixed %59, 0, killed %60, 14, $noreg 204 %22:gpr = ADDri %stack.1.jb1, 0, 14, $noreg, $noreg 205 $r0 = COPY killed %22 206 $r2 = COPY killed %18 207 $r3 = COPY killed %19 208 BL @_Z3fooPx3S18z, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit killed $r0, implicit killed $r2, implicit killed $r3, implicit-def $sp 209 ADJCALLSTACKUP 64, 0, 14, $noreg, implicit-def dead $sp, implicit $sp 210 bb.6: 211 %16:gpr = MOVi 0, 14, $noreg, $noreg 212 $r0 = COPY killed %16 213 BX_RET 14, $noreg, implicit killed $r0 214... 215