llvm.org GIT mirror llvm / 1c7d69b
PR12716: PPC crashes on vector compare Vector compare using altivec 'vcmpxxx' instructions have as third argument a vector register instead of CR one, different from integer and float-point compares. This leads to a failure in code generation, where 'SelectSETCC' expects a DAG with a CR register and gets vector register instead. This patch changes the behavior by just returning a DAG with the vector compare instruction based on the type. The patch also adds a testcase for all vector types llvm defines. It also included a fix on signed 5-bits predicates printing, where signed values were not handled correctly as signed (char are unsigned by default for PowerPC). This generates 'vspltisw' (vector splat) instruction with SIM out of range. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165419 91177308-0d34-0410-b5e6-96231b3b80d8 Adhemerval Zanella 7 years ago
4 changed file(s) with 218 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
135135
136136 void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo,
137137 raw_ostream &O) {
138 char Value = MI->getOperand(OpNo).getImm();
138 int Value = MI->getOperand(OpNo).getImm();
139139 Value = SignExtend32<5>(Value);
140140 O << (int)Value;
141141 }
142142
143143 void PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo,
144144 raw_ostream &O) {
145 unsigned char Value = MI->getOperand(OpNo).getImm();
145 unsigned int Value = MI->getOperand(OpNo).getImm();
146146 assert(Value <= 31 && "Invalid u5imm argument!");
147147 O << (unsigned int)Value;
148148 }
149149
150150 void PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo,
151151 raw_ostream &O) {
152 unsigned char Value = MI->getOperand(OpNo).getImm();
152 unsigned int Value = MI->getOperand(OpNo).getImm();
153153 assert(Value <= 63 && "Invalid u6imm argument!");
154154 O << (unsigned int)Value;
155155 }
700700 }
701701 }
702702
703 SDValue LHS = N->getOperand(0);
704 SDValue RHS = N->getOperand(1);
705
706 // Altivec Vector compare instructions do not set any CR register by default
707 if (LHS.getValueType().isVector()) {
708 unsigned int Opc;
709 if (LHS.getValueType() == MVT::v16i8)
710 Opc = PPC::VCMPEQUB;
711 else if (LHS.getValueType() == MVT::v4i32)
712 Opc = PPC::VCMPEQUW;
713 else if (LHS.getValueType() == MVT::v8i16)
714 Opc = PPC::VCMPEQUH;
715 else if (LHS.getValueType() == MVT::v4f32)
716 Opc = PPC::VCMPEQFP;
717 else
718 llvm_unreachable("Invalid vector compare type: should be expanded by legalize");
719 return CurDAG->SelectNodeTo(N, Opc, LHS.getValueType(), LHS, RHS);
720 }
721
703722 bool Inv;
704723 int OtherCondIdx;
705724 unsigned Idx = getCRIdxForSetCC(CC, Inv, OtherCondIdx);
706 SDValue CCReg = SelectCC(N->getOperand(0), N->getOperand(1), CC, dl);
725 SDValue CCReg = SelectCC(LHS, RHS, CC, dl);
707726 SDValue IntCR;
708727
709728 // Force the ccreg into CR7.
716735 if (PPCSubTarget.hasMFOCRF() && OtherCondIdx == -1)
717736 IntCR = SDValue(CurDAG->getMachineNode(PPC::MFOCRF, dl, MVT::i32, CR7Reg,
718737 CCReg), 0);
719 else
738 else
720739 IntCR = SDValue(CurDAG->getMachineNode(PPC::MFCRpseud, dl, MVT::i32,
721740 CR7Reg, CCReg), 0);
722741
541541 }
542542
543543 EVT PPCTargetLowering::getSetCCResultType(EVT VT) const {
544 return MVT::i32;
544 if (!VT.isVector())
545 return MVT::i32;
546 return VT.changeVectorElementTypeToInteger();
545547 }
546548
547549 //===----------------------------------------------------------------------===//
0 ; RUN: llc -mattr=+altivec < %s | FileCheck %s
1
2 ; Check vector comparisons using altivec.
3
4
5 target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64"
6 target triple = "powerpc64-unknown-linux-gnu"
7
8 define <2 x i8> @v2si8_cmp(<2 x i8> %x, <2 x i8> %y) nounwind readnone {
9 %cmp = icmp eq <2 x i8> %x, %y
10 %sext = sext <2 x i1> %cmp to <2 x i8>
11 ret <2 x i8> %sext
12 }
13 ; CHECK: v2si8_cmp:
14 ; CHECK: vcmpequb {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
15
16
17 define <4 x i8> @v4si8_cmp(<4 x i8> %x, <4 x i8> %y) nounwind readnone {
18 %cmp = icmp eq <4 x i8> %x, %y
19 %sext = sext <4 x i1> %cmp to <4 x i8>
20 ret <4 x i8> %sext
21 }
22 ; CHECK: v4si8_cmp:
23 ; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
24
25
26 define <8 x i8> @v8si8_cmp(<8 x i8> %x, <8 x i8> %y) nounwind readnone {
27 %cmp = icmp eq <8 x i8> %x, %y
28 %sext = sext <8 x i1> %cmp to <8 x i8>
29 ret <8 x i8> %sext
30 }
31 ; CHECK: v8si8_cmp:
32 ; CHECK: vcmpequh {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
33
34
35 define <16 x i8> @v16si8_cmp(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
36 %cmp = icmp eq <16 x i8> %x, %y
37 %sext = sext <16 x i1> %cmp to <16 x i8>
38 ret <16 x i8> %sext
39 }
40 ; CHECK: v16si8_cmp:
41 ; CHECK: vcmpequb {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
42
43
44 define <32 x i8> @v32si8_cmp(<32 x i8> %x, <32 x i8> %y) nounwind readnone {
45 %cmp = icmp eq <32 x i8> %x, %y
46 %sext = sext <32 x i1> %cmp to <32 x i8>
47 ret <32 x i8> %sext
48 }
49 ; CHECK: v32si8_cmp:
50 ; CHECK: vcmpequb {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
51 ; CHECK: vcmpequb {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
52
53
54 define <2 x i16> @v2si16_cmp(<2 x i16> %x, <2 x i16> %y) nounwind readnone {
55 %cmp = icmp eq <2 x i16> %x, %y
56 %sext = sext <2 x i1> %cmp to <2 x i16>
57 ret <2 x i16> %sext
58 }
59 ; CHECK: v2si16_cmp:
60 ; CHECK: vcmpequh {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
61
62
63 define <4 x i16> @v4si16_cmp(<4 x i16> %x, <4 x i16> %y) nounwind readnone {
64 %cmp = icmp eq <4 x i16> %x, %y
65 %sext = sext <4 x i1> %cmp to <4 x i16>
66 ret <4 x i16> %sext
67 }
68 ; CHECK: v4si16_cmp:
69 ; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
70
71
72 define <8 x i16> @v8si16_cmp(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
73 %cmp = icmp eq <8 x i16> %x, %y
74 %sext = sext <8 x i1> %cmp to <8 x i16>
75 ret <8 x i16> %sext
76 }
77 ; CHECK: v8si16_cmp:
78 ; CHECK: vcmpequh {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
79
80
81 define <16 x i16> @v16si16_cmp(<16 x i16> %x, <16 x i16> %y) nounwind readnone {
82 %cmp = icmp eq <16 x i16> %x, %y
83 %sext = sext <16 x i1> %cmp to <16 x i16>
84 ret <16 x i16> %sext
85 }
86 ; CHECK: v16si16_cmp:
87 ; CHECK: vcmpequh {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
88 ; CHECK: vcmpequh {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
89
90
91 define <32 x i16> @v32si16_cmp(<32 x i16> %x, <32 x i16> %y) nounwind readnone {
92 %cmp = icmp eq <32 x i16> %x, %y
93 %sext = sext <32 x i1> %cmp to <32 x i16>
94 ret <32 x i16> %sext
95 }
96 ; CHECK: v32si16_cmp:
97 ; CHECK: vcmpequh {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
98 ; CHECK: vcmpequh {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
99 ; CHECK: vcmpequh {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
100 ; CHECK: vcmpequh {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
101
102
103 define <2 x i32> @v2si32_cmp(<2 x i32> %x, <2 x i32> %y) nounwind readnone {
104 %cmp = icmp eq <2 x i32> %x, %y
105 %sext = sext <2 x i1> %cmp to <2 x i32>
106 ret <2 x i32> %sext
107 }
108 ; CHECK: v2si32_cmp:
109 ; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
110
111
112 define <4 x i32> @v4si32_cmp(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
113 %cmp = icmp eq <4 x i32> %x, %y
114 %sext = sext <4 x i1> %cmp to <4 x i32>
115 ret <4 x i32> %sext
116 }
117 ; CHECK: v4si32_cmp:
118 ; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
119
120
121 define <8 x i32> @v8si32_cmp(<8 x i32> %x, <8 x i32> %y) nounwind readnone {
122 %cmp = icmp eq <8 x i32> %x, %y
123 %sext = sext <8 x i1> %cmp to <8 x i32>
124 ret <8 x i32> %sext
125 }
126 ; CHECK: v8si32_cmp:
127 ; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
128 ; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
129
130
131 define <16 x i32> @v16si32_cmp(<16 x i32> %x, <16 x i32> %y) nounwind readnone {
132 %cmp = icmp eq <16 x i32> %x, %y
133 %sext = sext <16 x i1> %cmp to <16 x i32>
134 ret <16 x i32> %sext
135 }
136 ; CHECK: v16si32_cmp:
137 ; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
138 ; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
139 ; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
140 ; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
141
142
143 define <32 x i32> @v32si32_cmp(<32 x i32> %x, <32 x i32> %y) nounwind readnone {
144 %cmp = icmp eq <32 x i32> %x, %y
145 %sext = sext <32 x i1> %cmp to <32 x i32>
146 ret <32 x i32> %sext
147 }
148 ; CHECK: v32si32_cmp:
149 ; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
150 ; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
151 ; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
152 ; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
153 ; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
154 ; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
155 ; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
156 ; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
157
158
159 define <2 x float> @v2f32_cmp(<2 x float> %x, <2 x float> %y) nounwind readnone {
160 entry:
161 %cmp = fcmp oeq <2 x float> %x, %y
162 %sext = sext <2 x i1> %cmp to <2 x i32>
163 %0 = bitcast <2 x i32> %sext to <2 x float>
164 ret <2 x float> %0
165 }
166 ; CHECK: v2f32_cmp:
167 ; CHECK: vcmpeqfp {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
168
169
170 define <4 x float> @v4f32_cmp(<4 x float> %x, <4 x float> %y) nounwind readnone {
171 entry:
172 %cmp = fcmp oeq <4 x float> %x, %y
173 %sext = sext <4 x i1> %cmp to <4 x i32>
174 %0 = bitcast <4 x i32> %sext to <4 x float>
175 ret <4 x float> %0
176 }
177 ; CHECK: v4f32_cmp:
178 ; CHECK: vcmpeqfp {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
179
180
181 define <8 x float> @v8f32_cmp(<8 x float> %x, <8 x float> %y) nounwind readnone {
182 entry:
183 %cmp = fcmp oeq <8 x float> %x, %y
184 %sext = sext <8 x i1> %cmp to <8 x i32>
185 %0 = bitcast <8 x i32> %sext to <8 x float>
186 ret <8 x float> %0
187 }
188 ; CHECK: v8f32_cmp:
189 ; CHECK: vcmpeqfp {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
190 ; CHECK: vcmpeqfp {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}