llvm.org GIT mirror llvm / 97a3597
Merging r217993: ------------------------------------------------------------------------ r217993 | sfantao | 2014-09-17 23:25:06 +0000 (Wed, 17 Sep 2014) | 5 lines Fix FastISel bug in boolean returns for PowerPC. For PPC targets, FastISel does not take the sign extension information into account when selecting return instructions whose operands are constants. A consequence of this is that the return of boolean values is not correct. This patch fixes the problem by evaluating the sign extension information also for constants, forwarding this information to PPCMaterializeInt which takes this information to drive the sign extension during the materialization. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_35@223739 91177308-0d34-0410-b5e6-96231b3b80d8 Hal Finkel 5 years ago
2 changed file(s) with 67 addition(s) and 24 deletion(s). Raw diff Collapse all Expand all
152152 unsigned DestReg, bool IsZExt);
153153 unsigned PPCMaterializeFP(const ConstantFP *CFP, MVT VT);
154154 unsigned PPCMaterializeGV(const GlobalValue *GV, MVT VT);
155 unsigned PPCMaterializeInt(const Constant *C, MVT VT);
155 unsigned PPCMaterializeInt(const Constant *C, MVT VT, bool UseSExt = true);
156156 unsigned PPCMaterialize32BitInt(int64_t Imm,
157157 const TargetRegisterClass *RC);
158158 unsigned PPCMaterialize64BitInt(int64_t Imm,
15471547
15481548 // Special case for returning a constant integer of any size.
15491549 // Materialize the constant as an i64 and copy it to the return
1550 // register. This avoids an unnecessary extend or truncate.
1550 // register. We still need to worry about properly extending the sign. E.g:
1551 // If the constant has only one bit, it means it is a boolean. Therefore
1552 // we can't use PPCMaterializeInt because it extends the sign which will
1553 // cause negations of the returned value to be incorrect as they are
1554 // implemented as the flip of the least significant bit.
15511555 if (isa(*RV)) {
15521556 const Constant *C = cast(RV);
1553 unsigned SrcReg = PPCMaterializeInt(C, MVT::i64);
1554 unsigned RetReg = ValLocs[0].getLocReg();
1557
1558 CCValAssign &VA = ValLocs[0];
1559
1560 unsigned RetReg = VA.getLocReg();
1561 unsigned SrcReg = PPCMaterializeInt(C, MVT::i64,
1562 VA.getLocInfo() == CCValAssign::SExt);
1563
15551564 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1556 TII.get(TargetOpcode::COPY), RetReg).addReg(SrcReg);
1565 TII.get(TargetOpcode::COPY), RetReg).addReg(SrcReg);
1566
15571567 RetRegs.push_back(RetReg);
15581568
15591569 } else {
20132023
20142024 // Materialize an integer constant into a register, and return
20152025 // the register number (or zero if we failed to handle it).
2016 unsigned PPCFastISel::PPCMaterializeInt(const Constant *C, MVT VT) {
2026 unsigned PPCFastISel::PPCMaterializeInt(const Constant *C, MVT VT,
2027 bool UseSExt) {
20172028 // If we're using CR bit registers for i1 values, handle that as a special
20182029 // case first.
20192030 if (VT == MVT::i1 && PPCSubTarget->useCRBits()) {
20372048 unsigned Opc = (VT == MVT::i64) ? PPC::LI8 : PPC::LI;
20382049 unsigned ImmReg = createResultReg(RC);
20392050 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ImmReg)
2040 .addImm(CI->getSExtValue());
2051 .addImm( (UseSExt) ? CI->getSExtValue() : CI->getZExtValue() );
20412052 return ImmReg;
20422053 }
20432054
0 ; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 | FileCheck %s --check-prefix=ELF64
1
2 define zeroext i1 @rettrue() nounwind uwtable ssp {
3 entry:
4 ; ELF64-LABEL: rettrue
5 ; ELF64: li 3, 1
6 ; ELF64: blr
7 ret i1 true
8 }
9
10 define zeroext i1 @retfalse() nounwind uwtable ssp {
11 entry:
12 ; ELF64-LABEL: retfalse
13 ; ELF64: li 3, 0
14 ; ELF64: blr
15 ret i1 false
16 }
17
18 define signext i1 @retstrue() nounwind uwtable ssp {
19 entry:
20 ; ELF64-LABEL: retstrue
21 ; ELF64: li 3, -1
22 ; ELF64: blr
23 ret i1 true
24 }
25
26 define signext i1 @retsfalse() nounwind uwtable ssp {
27 entry:
28 ; ELF64-LABEL: retsfalse
29 ; ELF64: li 3, 0
30 ; ELF64: blr
31 ret i1 false
32 }
133
234 define signext i8 @ret2(i8 signext %a) nounwind uwtable ssp {
335 entry:
4 ; ELF64: ret2
36 ; ELF64-LABEL: ret2
537 ; ELF64: extsb
638 ; ELF64: blr
739 ret i8 %a
941
1042 define zeroext i8 @ret3(i8 signext %a) nounwind uwtable ssp {
1143 entry:
12 ; ELF64: ret3
44 ; ELF64-LABEL: ret3
1345 ; ELF64: rldicl {{[0-9]+}}, {{[0-9]+}}, 0, 56
1446 ; ELF64: blr
1547 ret i8 %a
1749
1850 define signext i16 @ret4(i16 signext %a) nounwind uwtable ssp {
1951 entry:
20 ; ELF64: ret4
52 ; ELF64-LABEL: ret4
2153 ; ELF64: extsh
2254 ; ELF64: blr
2355 ret i16 %a
2557
2658 define zeroext i16 @ret5(i16 signext %a) nounwind uwtable ssp {
2759 entry:
28 ; ELF64: ret5
60 ; ELF64-LABEL: ret5
2961 ; ELF64: rldicl {{[0-9]+}}, {{[0-9]+}}, 0, 48
3062 ; ELF64: blr
3163 ret i16 %a
3365
3466 define i16 @ret6(i16 %a) nounwind uwtable ssp {
3567 entry:
36 ; ELF64: ret6
68 ; ELF64-LABEL: ret6
3769 ; ELF64: rldicl {{[0-9]+}}, {{[0-9]+}}, 0, 48
3870 ; ELF64: blr
3971 ret i16 %a
4173
4274 define signext i32 @ret7(i32 signext %a) nounwind uwtable ssp {
4375 entry:
44 ; ELF64: ret7
76 ; ELF64-LABEL: ret7
4577 ; ELF64: extsw
4678 ; ELF64: blr
4779 ret i32 %a
4981
5082 define zeroext i32 @ret8(i32 signext %a) nounwind uwtable ssp {
5183 entry:
52 ; ELF64: ret8
84 ; ELF64-LABEL: ret8
5385 ; ELF64: rldicl {{[0-9]+}}, {{[0-9]+}}, 0, 32
5486 ; ELF64: blr
5587 ret i32 %a
5789
5890 define i32 @ret9(i32 %a) nounwind uwtable ssp {
5991 entry:
60 ; ELF64: ret9
92 ; ELF64-LABEL: ret9
6193 ; ELF64: rldicl {{[0-9]+}}, {{[0-9]+}}, 0, 32
6294 ; ELF64: blr
6395 ret i32 %a
6597
6698 define i64 @ret10(i64 %a) nounwind uwtable ssp {
6799 entry:
68 ; ELF64: ret10
100 ; ELF64-LABEL: ret10
69101 ; ELF64-NOT: exts
70102 ; ELF64-NOT: rldicl
71103 ; ELF64: blr
74106
75107 define float @ret11(float %a) nounwind uwtable ssp {
76108 entry:
77 ; ELF64: ret11
109 ; ELF64-LABEL: ret11
78110 ; ELF64: blr
79111 ret float %a
80112 }
81113
82114 define double @ret12(double %a) nounwind uwtable ssp {
83115 entry:
84 ; ELF64: ret12
116 ; ELF64-LABEL: ret12
85117 ; ELF64: blr
86118 ret double %a
87119 }
88120
89121 define i8 @ret13() nounwind uwtable ssp {
90122 entry:
91 ; ELF64: ret13
123 ; ELF64-LABEL: ret13
92124 ; ELF64: li
93125 ; ELF64: blr
94126 ret i8 15;
96128
97129 define i16 @ret14() nounwind uwtable ssp {
98130 entry:
99 ; ELF64: ret14
131 ; ELF64-LABEL: ret14
100132 ; ELF64: li
101133 ; ELF64: blr
102134 ret i16 -225;
104136
105137 define i32 @ret15() nounwind uwtable ssp {
106138 entry:
107 ; ELF64: ret15
139 ; ELF64-LABEL: ret15
108140 ; ELF64: lis
109141 ; ELF64: ori
110142 ; ELF64: blr
113145
114146 define i64 @ret16() nounwind uwtable ssp {
115147 entry:
116 ; ELF64: ret16
148 ; ELF64-LABEL: ret16
117149 ; ELF64: li
118150 ; ELF64: sldi
119151 ; ELF64: oris
124156
125157 define float @ret17() nounwind uwtable ssp {
126158 entry:
127 ; ELF64: ret17
159 ; ELF64-LABEL: ret17
128160 ; ELF64: addis
129161 ; ELF64: lfs
130162 ; ELF64: blr
133165
134166 define double @ret18() nounwind uwtable ssp {
135167 entry:
136 ; ELF64: ret18
168 ; ELF64-LABEL: ret18
137169 ; ELF64: addis
138170 ; ELF64: lfd
139171 ; ELF64: blr