1 ; RUN: llc -march=xcore < %s | FileCheck %s 2 ; RUN: llc -march=xcore -O=0 < %s | FileCheck %s -check-prefix=PHINODE 3 4 declare i8 addrspace(1)* @llvm.xcore.getst.p1i8.p1i8(i8 addrspace(1)* %r) 5 declare void @llvm.xcore.msync.p1i8(i8 addrspace(1)* %r) 6 declare void @llvm.xcore.ssync() 7 declare void @llvm.xcore.mjoin.p1i8(i8 addrspace(1)* %r) 8 declare void @llvm.xcore.initsp.p1i8(i8 addrspace(1)* %r, i8* %value) 9 declare void @llvm.xcore.initpc.p1i8(i8 addrspace(1)* %r, i8* %value) 10 declare void @llvm.xcore.initlr.p1i8(i8 addrspace(1)* %r, i8* %value) 11 declare void @llvm.xcore.initcp.p1i8(i8 addrspace(1)* %r, i8* %value) 12 declare void @llvm.xcore.initdp.p1i8(i8 addrspace(1)* %r, i8* %value) 13 14 define i8 addrspace(1)* @test_getst(i8 addrspace(1)* %r) { 15 ; CHECK-LABEL: test_getst: 16 ; CHECK: getst r0, res[r0] 17 %result = call i8 addrspace(1)* @llvm.xcore.getst.p1i8.p1i8(i8 addrspace(1)* %r) 18 ret i8 addrspace(1)* %result 19 } 20 21 define void @test_ssync() { 22 ; CHECK-LABEL: test_ssync: 23 ; CHECK: ssync 24 call void @llvm.xcore.ssync() 25 ret void 26 } 27 28 define void @test_mjoin(i8 addrspace(1)* %r) { 29 ; CHECK-LABEL: test_mjoin: 30 ; CHECK: mjoin res[r0] 31 call void @llvm.xcore.mjoin.p1i8(i8 addrspace(1)* %r) 32 ret void 33 } 34 35 define void @test_initsp(i8 addrspace(1)* %t, i8* %src) { 36 ; CHECK-LABEL: test_initsp: 37 ; CHECK: init t[r0]:sp, r1 38 call void @llvm.xcore.initsp.p1i8(i8 addrspace(1)* %t, i8* %src) 39 ret void 40 } 41 42 define void @test_initpc(i8 addrspace(1)* %t, i8* %src) { 43 ; CHECK-LABEL: test_initpc: 44 ; CHECK: init t[r0]:pc, r1 45 call void @llvm.xcore.initpc.p1i8(i8 addrspace(1)* %t, i8* %src) 46 ret void 47 } 48 49 define void @test_initlr(i8 addrspace(1)* %t, i8* %src) { 50 ; CHECK-LABEL: test_initlr: 51 ; CHECK: init t[r0]:lr, r1 52 call void @llvm.xcore.initlr.p1i8(i8 addrspace(1)* %t, i8* %src) 53 ret void 54 } 55 56 define void @test_initcp(i8 addrspace(1)* %t, i8* %src) { 57 ; CHECK-LABEL: test_initcp: 58 ; CHECK: init t[r0]:cp, r1 59 call void @llvm.xcore.initcp.p1i8(i8 addrspace(1)* %t, i8* %src) 60 ret void 61 } 62 63 define void @test_initdp(i8 addrspace(1)* %t, i8* %src) { 64 ; CHECK-LABEL: test_initdp: 65 ; CHECK: init t[r0]:dp, r1 66 call void @llvm.xcore.initdp.p1i8(i8 addrspace(1)* %t, i8* %src) 67 ret void 68 } 69 70 @tl = thread_local global [3 x i32] zeroinitializer 71 @tle = external thread_local global [2 x i32] 72 73 define i32* @f_tl() { 74 ; CHECK-LABEL: f_tl: 75 ; CHECK: get r11, id 76 ; CHECK: ldaw [[R0:r[0-9]]], dp[tl] 77 ; CHECK: ldc [[R1:r[0-9]]], 8 78 ; CHECK: ldc [[R2:r[0-9]]], 12 79 ; r0 = id*12 + 8 + &tl 80 ; CHECK: lmul {{r[0-9]}}, r0, r11, [[R2]], [[R0]], [[R1]] 81 ret i32* getelementptr inbounds ([3 x i32]* @tl, i32 0, i32 2) 82 } 83 84 define i32* @f_tle() { 85 ; CHECK-LABEL: f_tle: 86 ; CHECK: get r11, id 87 ; CHECK: shl [[R0:r[0-9]]], r11, 3 88 ; CHECK: ldaw [[R1:r[0-9]]], dp[tle] 89 ; r0 = &tl + id*8 90 ; CHECK: add r0, [[R1]], [[R0]] 91 ret i32* getelementptr inbounds ([2 x i32]* @tle, i32 0, i32 0) 92 } 93 94 define i32 @f_tlExpr () { 95 ; CHECK-LABEL: f_tlExpr: 96 ; CHECK: get r11, id 97 ; CHECK: shl [[R0:r[0-9]]], r11, 3 98 ; CHECK: ldaw [[R1:r[0-9]]], dp[tle] 99 ; CHECK: add [[R2:r[0-9]]], [[R1]], [[R0]] 100 ; CHECK: add r0, [[R2]], [[R2]] 101 ret i32 add( 102 i32 ptrtoint( i32* getelementptr inbounds ([2 x i32]* @tle, i32 0, i32 0) to i32), 103 i32 ptrtoint( i32* getelementptr inbounds ([2 x i32]* @tle, i32 0, i32 0) to i32)) 104 } 105 106 define void @phiNode1() { 107 ; N.B. lowering of duplicate constexpr in a PHI node requires -O=0 108 ; PHINODE-LABEL: phiNode1: 109 ; PHINODE: get r11, id 110 ; PHINODE-LABEL: .LBB11_1: 111 ; PHINODE: get r11, id 112 ; PHINODE: bu .LBB11_1 113 entry: 114 br label %ConstantExpPhiNode 115 ConstantExpPhiNode: 116 %ptr = phi i32* [ getelementptr inbounds ([3 x i32]* @tl, i32 0, i32 0), %entry ], 117 [ getelementptr inbounds ([3 x i32]* @tl, i32 0, i32 0), %ConstantExpPhiNode ] 118 br label %ConstantExpPhiNode 119 exit: 120 ret void 121 } 122 123 define void @phiNode2( i1 %bool) { 124 ; N.B. check an extra 'Node_crit_edge' (LBB12_1) is inserted 125 ; PHINODE-LABEL: phiNode2: 126 ; PHINODE: bf {{r[0-9]}}, .LBB12_3 127 ; PHINODE: bu .LBB12_1 128 ; PHINODE-LABEL: .LBB12_1: 129 ; PHINODE: get r11, id 130 ; PHINODE-LABEL: .LBB12_2: 131 ; PHINODE: get r11, id 132 ; PHINODE: bu .LBB12_2 133 ; PHINODE-LABEL: .LBB12_3: 134 entry: 135 br i1 %bool, label %ConstantExpPhiNode, label %exit 136 ConstantExpPhiNode: 137 %ptr = phi i32* [ getelementptr inbounds ([3 x i32]* @tl, i32 0, i32 0), %entry ], 138 [ getelementptr inbounds ([3 x i32]* @tl, i32 0, i32 0), %ConstantExpPhiNode ] 139 br label %ConstantExpPhiNode 140 exit: 141 ret void 142 } 143 144 ; CHECK-LABEL: tl: 145 ; CHECK: .space 96 146