1; RUN: llc -march=xcore < %s | FileCheck %s 2; RUN: llc -march=xcore -O=0 < %s | FileCheck %s -check-prefix=PHINODE 3 4declare i8 addrspace(1)* @llvm.xcore.getst.p1i8.p1i8(i8 addrspace(1)* %r) 5declare void @llvm.xcore.msync.p1i8(i8 addrspace(1)* %r) 6declare void @llvm.xcore.ssync() 7declare void @llvm.xcore.mjoin.p1i8(i8 addrspace(1)* %r) 8declare void @llvm.xcore.initsp.p1i8(i8 addrspace(1)* %r, i8* %value) 9declare void @llvm.xcore.initpc.p1i8(i8 addrspace(1)* %r, i8* %value) 10declare void @llvm.xcore.initlr.p1i8(i8 addrspace(1)* %r, i8* %value) 11declare void @llvm.xcore.initcp.p1i8(i8 addrspace(1)* %r, i8* %value) 12declare void @llvm.xcore.initdp.p1i8(i8 addrspace(1)* %r, i8* %value) 13 14define 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 21define void @test_ssync() { 22; CHECK-LABEL: test_ssync: 23; CHECK: ssync 24 call void @llvm.xcore.ssync() 25 ret void 26} 27 28define 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 35define 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 42define 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 49define 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 56define 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 63define 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 73define 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], [3 x i32]* @tl, i32 0, i32 2) 82} 83 84define 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], [2 x i32]* @tle, i32 0, i32 0) 92} 93 94define 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], [2 x i32]* @tle, i32 0, i32 0) to i32), 103 i32 ptrtoint( i32* getelementptr inbounds ([2 x i32], [2 x i32]* @tle, i32 0, i32 0) to i32)) 104} 105 106define 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 113entry: 114 br label %ConstantExpPhiNode 115ConstantExpPhiNode: 116 %ptr = phi i32* [ getelementptr inbounds ([3 x i32], [3 x i32]* @tl, i32 0, i32 0), %entry ], 117 [ getelementptr inbounds ([3 x i32], [3 x i32]* @tl, i32 0, i32 0), %ConstantExpPhiNode ] 118 br label %ConstantExpPhiNode 119exit: 120 ret void 121} 122 123define 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: 134entry: 135 br i1 %bool, label %ConstantExpPhiNode, label %exit 136ConstantExpPhiNode: 137 %ptr = phi i32* [ getelementptr inbounds ([3 x i32], [3 x i32]* @tl, i32 0, i32 0), %entry ], 138 [ getelementptr inbounds ([3 x i32], [3 x i32]* @tl, i32 0, i32 0), %ConstantExpPhiNode ] 139 br label %ConstantExpPhiNode 140exit: 141 ret void 142} 143 144; CHECK-LABEL: tl: 145; CHECK: .space 96 146