llvm.org GIT mirror llvm / b45b9d6
Merging r223318: ------------------------------------------------------------------------ r223318 | hfinkel | 2014-12-03 23:40:13 +0000 (Wed, 03 Dec 2014) | 12 lines [PowerPC] Fix inline asm memory operands not to use r0 On PowerPC, inline asm memory operands might be expanded as 0($r), where $r is a register containing the address. As a result, this register cannot be r0, and we need to enforce this register subclass constraint to prevent miscompiling the code (we'd get this constraint for free with the usual instruction definitions, but that scheme has no knowledge of how we end up printing inline asm memory operands, and so here we need to do it 'by hand'). We can accomplish this within the current address-mode selection framework by introducing an explicit COPY_TO_REGCLASS node. Fixes PR21443. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_35@223746 91177308-0d34-0410-b5e6-96231b3b80d8 Hal Finkel 5 years ago
2 changed file(s) with 106 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
171171 /// a register. The case of adding a (possibly relocatable) constant to a
172172 /// register can be improved, but it is wrong to substitute Reg+Reg for
173173 /// Reg in an asm, because the load or store opcode would have to change.
174 bool SelectInlineAsmMemoryOperand(const SDValue &Op,
174 bool SelectInlineAsmMemoryOperand(const SDValue &Op,
175175 char ConstraintCode,
176176 std::vector &OutOps) override {
177 OutOps.push_back(Op);
177 // We need to make sure that this one operand does not end up in r0
178 // (because we might end up lowering this as 0(%op)).
179 const TargetRegisterInfo *TRI = TM.getSubtargetImpl()->getRegisterInfo();
180 const TargetRegisterClass *TRC = TRI->getPointerRegClass(*MF, /*Kind=*/1);
181 SDValue RC = CurDAG->getTargetConstant(TRC->getID(), MVT::i32);
182 SDValue NewOp =
183 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
184 SDLoc(Op), Op.getValueType(),
185 Op, RC), 0);
186
187 OutOps.push_back(NewOp);
178188 return false;
179189 }
180190
0 ; RUN: llc -mcpu=pwr7 < %s | FileCheck %s
1 target datalayout = "e-m:e-i64:64-n32:64"
2 target triple = "powerpc64le-unknown-linux-gnu"
3
4 ; Make sure that we don't generate a std r, 0(0) -- the memory address cannot
5 ; be stored in r0.
6 ; CHECK-LABEL: @test1
7 ; CHECK-NOT: std {{[0-9]+}}, 0(0)
8 ; CHECK: blr
9
10 define void @test1({ i8*, void (i8*, i8*)* } %fn_arg) {
11 %fn = alloca { i8*, void (i8*, i8*)* }
12 %sp = alloca i8*, align 8
13 %regs = alloca [18 x i64], align 8
14 store { i8*, void (i8*, i8*)* } %fn_arg, { i8*, void (i8*, i8*)* }* %fn
15 %1 = bitcast [18 x i64]* %regs to i64*
16 call void asm sideeffect "std 14, $0", "=*m"(i64* %1)
17 %2 = bitcast [18 x i64]* %regs to i8*
18 %3 = getelementptr i8* %2, i32 8
19 %4 = bitcast i8* %3 to i64*
20 call void asm sideeffect "std 15, $0", "=*m"(i64* %4)
21 %5 = bitcast [18 x i64]* %regs to i8*
22 %6 = getelementptr i8* %5, i32 16
23 %7 = bitcast i8* %6 to i64*
24 call void asm sideeffect "std 16, $0", "=*m"(i64* %7)
25 %8 = bitcast [18 x i64]* %regs to i8*
26 %9 = getelementptr i8* %8, i32 24
27 %10 = bitcast i8* %9 to i64*
28 call void asm sideeffect "std 17, $0", "=*m"(i64* %10)
29 %11 = bitcast [18 x i64]* %regs to i8*
30 %12 = getelementptr i8* %11, i32 32
31 %13 = bitcast i8* %12 to i64*
32 call void asm sideeffect "std 18, $0", "=*m"(i64* %13)
33 %14 = bitcast [18 x i64]* %regs to i8*
34 %15 = getelementptr i8* %14, i32 40
35 %16 = bitcast i8* %15 to i64*
36 call void asm sideeffect "std 19, $0", "=*m"(i64* %16)
37 %17 = bitcast [18 x i64]* %regs to i8*
38 %18 = getelementptr i8* %17, i32 48
39 %19 = bitcast i8* %18 to i64*
40 call void asm sideeffect "std 20, $0", "=*m"(i64* %19)
41 %20 = bitcast [18 x i64]* %regs to i8*
42 %21 = getelementptr i8* %20, i32 56
43 %22 = bitcast i8* %21 to i64*
44 call void asm sideeffect "std 21, $0", "=*m"(i64* %22)
45 %23 = bitcast [18 x i64]* %regs to i8*
46 %24 = getelementptr i8* %23, i32 64
47 %25 = bitcast i8* %24 to i64*
48 call void asm sideeffect "std 22, $0", "=*m"(i64* %25)
49 %26 = bitcast [18 x i64]* %regs to i8*
50 %27 = getelementptr i8* %26, i32 72
51 %28 = bitcast i8* %27 to i64*
52 call void asm sideeffect "std 23, $0", "=*m"(i64* %28)
53 %29 = bitcast [18 x i64]* %regs to i8*
54 %30 = getelementptr i8* %29, i32 80
55 %31 = bitcast i8* %30 to i64*
56 call void asm sideeffect "std 24, $0", "=*m"(i64* %31)
57 %32 = bitcast [18 x i64]* %regs to i8*
58 %33 = getelementptr i8* %32, i32 88
59 %34 = bitcast i8* %33 to i64*
60 call void asm sideeffect "std 25, $0", "=*m"(i64* %34)
61 %35 = bitcast [18 x i64]* %regs to i8*
62 %36 = getelementptr i8* %35, i32 96
63 %37 = bitcast i8* %36 to i64*
64 call void asm sideeffect "std 26, $0", "=*m"(i64* %37)
65 %38 = bitcast [18 x i64]* %regs to i8*
66 %39 = getelementptr i8* %38, i32 104
67 %40 = bitcast i8* %39 to i64*
68 call void asm sideeffect "std 27, $0", "=*m"(i64* %40)
69 %41 = bitcast [18 x i64]* %regs to i8*
70 %42 = getelementptr i8* %41, i32 112
71 %43 = bitcast i8* %42 to i64*
72 call void asm sideeffect "std 28, $0", "=*m"(i64* %43)
73 %44 = bitcast [18 x i64]* %regs to i8*
74 %45 = getelementptr i8* %44, i32 120
75 %46 = bitcast i8* %45 to i64*
76 call void asm sideeffect "std 29, $0", "=*m"(i64* %46)
77 %47 = bitcast [18 x i64]* %regs to i8*
78 %48 = getelementptr i8* %47, i32 128
79 %49 = bitcast i8* %48 to i64*
80 call void asm sideeffect "std 30, $0", "=*m"(i64* %49)
81 %50 = bitcast [18 x i64]* %regs to i8*
82 %51 = getelementptr i8* %50, i32 136
83 %52 = bitcast i8* %51 to i64*
84 call void asm sideeffect "std 31, $0", "=*m"(i64* %52)
85 %53 = getelementptr { i8*, void (i8*, i8*)* }* %fn, i32 0, i32 1
86 %.funcptr = load void (i8*, i8*)** %53
87 %54 = getelementptr { i8*, void (i8*, i8*)* }* %fn, i32 0, i32 0
88 %.ptr = load i8** %54
89 %55 = load i8** %sp
90 call void %.funcptr(i8* %.ptr, i8* %55)
91 ret void
92 }
93