comparison gen/complex.cpp @ 617:634fbbdec390

Simplify complex number handling. Fixes bug with complex substraction.
author Christian Kamm <kamm incasoftware de>
date Mon, 22 Sep 2008 20:29:18 +0200
parents 192b82878b78
children 7e0a766fef47
comparison
equal deleted inserted replaced
616:5ced42a55aa9 617:634fbbdec390
86 86
87 ////////////////////////////////////////////////////////////////////////////////////////// 87 //////////////////////////////////////////////////////////////////////////////////////////
88 88
89 DValue* DtoComplex(Loc& loc, Type* to, DValue* val) 89 DValue* DtoComplex(Loc& loc, Type* to, DValue* val)
90 { 90 {
91 Type* t = val->getType()->toBasetype(); 91 const LLType* complexTy = DtoType(to);
92
93 if (t->iscomplex()) {
94 return DtoCastComplex(loc, val, to);
95 }
96
97 const LLType* base = DtoComplexBaseType(to);
98 92
99 Type* baserety; 93 Type* baserety;
100 Type* baseimty; 94 Type* baseimty;
101 TY ty = to->ty; 95 TY ty = to->ty;
102 if (ty == Tcomplex32) { 96 if (ty == Tcomplex32) {
111 } 105 }
112 else { 106 else {
113 assert(0); 107 assert(0);
114 } 108 }
115 109
116 const LLType* complexTy = DtoType(to); 110 LLValue *re, *im;
117 LLValue* res; 111 DtoGetComplexParts(loc, to, val, re, im);
118 112
119 if (t->isimaginary()) { 113 if(!re)
120 res = DtoAggrPair(complexTy, LLConstant::getNullValue(DtoType(baserety)), DtoCastFloat(loc, val, baseimty)->getRVal()); 114 re = LLConstant::getNullValue(DtoType(baserety));
121 } 115 if(!im)
122 else if (t->isfloating()) { 116 im = LLConstant::getNullValue(DtoType(baseimty));
123 res = DtoAggrPair(complexTy, DtoCastFloat(loc, val, baserety)->getRVal(), LLConstant::getNullValue(DtoType(baseimty))); 117
124 } 118 LLValue* res = DtoAggrPair(complexTy, re, im);
125 else if (t->isintegral()) { 119
126 res = DtoAggrPair(complexTy, DtoCastInt(loc, val, baserety)->getRVal(), LLConstant::getNullValue(DtoType(baseimty))); 120 return new DImValue(to, res);
121 }
122
123 //////////////////////////////////////////////////////////////////////////////////////////
124
125 void DtoComplexSet(LLValue* c, LLValue* re, LLValue* im)
126 {
127 DtoStore(re, DtoGEPi(c,0,0,"tmp"));
128 DtoStore(im, DtoGEPi(c,0,1,"tmp"));
129 }
130
131 //////////////////////////////////////////////////////////////////////////////////////////
132
133 void DtoGetComplexParts(Loc& loc, Type* to, DValue* val, LLValue*& re, LLValue*& im)
134 {
135 const LLType* base = DtoComplexBaseType(to);
136
137 Type* baserety;
138 Type* baseimty;
139 TY ty = to->ty;
140 if (ty == Tcomplex32) {
141 baserety = Type::tfloat32;
142 baseimty = Type::timaginary32;
143 } else if (ty == Tcomplex64) {
144 baserety = Type::tfloat64;
145 baseimty = Type::timaginary64;
146 } else if (ty == Tcomplex80) {
147 baserety = Type::tfloat80;
148 baseimty = Type::timaginary80;
127 } 149 }
128 else { 150 else {
129 assert(0); 151 assert(0);
130 } 152 }
131 return new DImValue(to, res); 153
132 } 154 Type* t = val->getType()->toBasetype();
133 155
134 ////////////////////////////////////////////////////////////////////////////////////////// 156 if (t->iscomplex()) {
135 157 DValue* v = DtoCastComplex(loc, val, to);
136 void DtoComplexSet(LLValue* c, LLValue* re, LLValue* im) 158 if (to->iscomplex()) {
137 { 159 re = gIR->ir->CreateExtractValue(v->getRVal(), 0, ".re_part");
138 DtoStore(re, DtoGEPi(c,0,0,"tmp")); 160 im = gIR->ir->CreateExtractValue(v->getRVal(), 1, ".im_part");
139 DtoStore(im, DtoGEPi(c,0,1,"tmp")); 161 } else
140 } 162 DtoGetComplexParts(loc, to, v, re, im);
141 163 }
142 ////////////////////////////////////////////////////////////////////////////////////////// 164 else if (t->isimaginary()) {
143 165 re = NULL;
144 void DtoGetComplexParts(DValue* c, LLValue*& re, LLValue*& im) 166 im = DtoCastFloat(loc, val, baseimty)->getRVal();
145 { 167 }
146 LLValue* v = c->getRVal(); 168 else if (t->isfloating()) {
147 Logger::cout() << "extracting real and imaginary parts from: " << *v << '\n'; 169 re = DtoCastFloat(loc, val, baserety)->getRVal();
148 re = gIR->ir->CreateExtractValue(v, 0, ".re_part"); 170 im = NULL;
149 im = gIR->ir->CreateExtractValue(v, 1, ".im_part"); 171 }
150 } 172 else if (t->isintegral()) {
151 173 re = DtoCastInt(loc, val, baserety)->getRVal();
152 DValue* resolveLR(DValue* val, bool getlval) 174 im = NULL;
153 { 175 }
154 if (DLRValue* lr = val->isLRValue()) { 176 else {
155 if (getlval) 177 assert(0);
156 return lr->lvalue; 178 }
157 else
158 return lr->rvalue;
159 }
160 return val;
161 }
162
163 //////////////////////////////////////////////////////////////////////////////////////////
164
165 bool hasRe(Type* t)
166 {
167 return
168 (t->ty != Timaginary32 &&
169 t->ty != Timaginary64 &&
170 t->ty != Timaginary80);
171 }
172
173 bool hasIm(Type* t)
174 {
175 return
176 (t->ty == Timaginary32 ||
177 t->ty == Timaginary64 ||
178 t->ty == Timaginary80 ||
179 t->ty == Tcomplex32 ||
180 t->ty == Tcomplex64 ||
181 t->ty == Tcomplex80);
182 } 179 }
183 180
184 ////////////////////////////////////////////////////////////////////////////////////////// 181 //////////////////////////////////////////////////////////////////////////////////////////
185 182
186 DValue* DtoComplexAdd(Loc& loc, Type* type, DValue* lhs, DValue* rhs) 183 DValue* DtoComplexAdd(Loc& loc, Type* type, DValue* lhs, DValue* rhs)
187 { 184 {
188 DValue* clhs = DtoComplex(loc, type, resolveLR(lhs, true));
189 DValue* crhs = DtoComplex(loc, type, resolveLR(rhs, false));
190
191 llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im; 185 llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;
192 186
193 // lhs values 187 // lhs values
194 DtoGetComplexParts(clhs, lhs_re, lhs_im); 188 DtoGetComplexParts(loc, type, lhs, lhs_re, lhs_im);
195 // rhs values 189 // rhs values
196 DtoGetComplexParts(crhs, rhs_re, rhs_im); 190 DtoGetComplexParts(loc, type, rhs, rhs_re, rhs_im);
197 191
198 // add up 192 // add up
199 Type* lhstype = lhs->getType(); 193 if(lhs_re && rhs_re)
200 Type* rhstype = rhs->getType();
201 if(hasRe(lhstype) && hasRe(rhstype))
202 res_re = gIR->ir->CreateAdd(lhs_re, rhs_re, "tmp"); 194 res_re = gIR->ir->CreateAdd(lhs_re, rhs_re, "tmp");
203 else if(hasRe(lhstype)) 195 else if(lhs_re)
204 res_re = lhs_re; 196 res_re = lhs_re;
205 else // either hasRe(rhstype) or no re at all (then use any) 197 else // either rhs_re or no re at all (then use any)
206 res_re = rhs_re; 198 res_re = rhs_re;
207 199
208 if(hasIm(lhstype) && hasIm(rhstype)) 200 if(lhs_im && rhs_im)
209 res_im = gIR->ir->CreateAdd(lhs_im, rhs_im, "tmp"); 201 res_im = gIR->ir->CreateAdd(lhs_im, rhs_im, "tmp");
210 else if(hasIm(lhstype)) 202 else if(lhs_im)
211 res_im = lhs_im; 203 res_im = lhs_im;
212 else // either hasIm(rhstype) or no im at all (then use any) 204 else // either rhs_im or no im at all (then use any)
213 res_im = rhs_im; 205 res_im = rhs_im;
214 206
215 LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im); 207 LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im);
216 return new DImValue(type, res); 208 return new DImValue(type, res);
217 } 209 }
218 210
219 ////////////////////////////////////////////////////////////////////////////////////////// 211 //////////////////////////////////////////////////////////////////////////////////////////
220 212
221 DValue* DtoComplexSub(Loc& loc, Type* type, DValue* lhs, DValue* rhs) 213 DValue* DtoComplexSub(Loc& loc, Type* type, DValue* lhs, DValue* rhs)
222 { 214 {
223 DValue* clhs = DtoComplex(loc, type, resolveLR(lhs, true));
224 DValue* crhs = DtoComplex(loc, type, resolveLR(rhs, false));
225
226 llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im; 215 llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;
227 216
228 // lhs values 217 // lhs values
229 DtoGetComplexParts(clhs, lhs_re, lhs_im); 218 DtoGetComplexParts(loc, type, lhs, lhs_re, lhs_im);
230 // rhs values 219 // rhs values
231 DtoGetComplexParts(crhs, rhs_re, rhs_im); 220 DtoGetComplexParts(loc, type, rhs, rhs_re, rhs_im);
232 221
233 // sub up 222 // add up
234 Type* lhstype = lhs->getType(); 223 if(lhs_re && rhs_re)
235 Type* rhstype = rhs->getType();
236 if(hasRe(rhstype))
237 res_re = gIR->ir->CreateSub(lhs_re, rhs_re, "tmp"); 224 res_re = gIR->ir->CreateSub(lhs_re, rhs_re, "tmp");
238 else 225 else if(lhs_re)
239 res_re = lhs_re; 226 res_re = lhs_re;
227 else // either rhs_re or no re at all (then use any)
228 res_re = gIR->ir->CreateNeg(rhs_re, "neg");
240 229
241 if(hasIm(rhstype)) 230 if(lhs_im && rhs_im)
242 res_im = gIR->ir->CreateSub(lhs_im, rhs_im, "tmp"); 231 res_im = gIR->ir->CreateSub(lhs_im, rhs_im, "tmp");
243 else 232 else if(lhs_im)
244 res_im = lhs_im; 233 res_im = lhs_im;
234 else // either rhs_im or no im at all (then use any)
235 res_im = gIR->ir->CreateNeg(rhs_im, "neg");
245 236
246 LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im); 237 LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im);
247 return new DImValue(type, res); 238 return new DImValue(type, res);
248 } 239 }
249 240
250 ////////////////////////////////////////////////////////////////////////////////////////// 241 //////////////////////////////////////////////////////////////////////////////////////////
251 242
252 DValue* DtoComplexMul(Loc& loc, Type* type, DValue* lhs, DValue* rhs) 243 DValue* DtoComplexMul(Loc& loc, Type* type, DValue* lhs, DValue* rhs)
253 { 244 {
254 DValue* clhs = DtoComplex(loc, type, resolveLR(lhs, true));
255 DValue* crhs = DtoComplex(loc, type, resolveLR(rhs, false));
256
257 llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im; 245 llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;
258 246
259 // lhs values 247 // lhs values
260 DtoGetComplexParts(clhs, lhs_re, lhs_im); 248 DtoGetComplexParts(loc, type, lhs, lhs_re, lhs_im);
261 // rhs values 249 // rhs values
262 DtoGetComplexParts(crhs, rhs_re, rhs_im); 250 DtoGetComplexParts(loc, type, rhs, rhs_re, rhs_im);
263 251
264 // mul up 252 // mul up
265 llvm::Value *rere = NULL; 253 llvm::Value *rere = NULL;
266 llvm::Value *reim = NULL; 254 llvm::Value *reim = NULL;
267 llvm::Value *imre = NULL; 255 llvm::Value *imre = NULL;
268 llvm::Value *imim = NULL; 256 llvm::Value *imim = NULL;
269 Type* lhstype = lhs->getType(); 257
270 Type* rhstype = rhs->getType(); 258 if(lhs_re && rhs_re)
271
272 if(hasRe(lhstype) && hasRe(rhstype))
273 rere = gIR->ir->CreateMul(lhs_re, rhs_re, "rere_mul"); 259 rere = gIR->ir->CreateMul(lhs_re, rhs_re, "rere_mul");
274 if(hasRe(lhstype) && hasIm(rhstype)) 260 if(lhs_re && rhs_im)
275 reim = gIR->ir->CreateMul(lhs_re, rhs_im, "reim_mul"); 261 reim = gIR->ir->CreateMul(lhs_re, rhs_im, "reim_mul");
276 if(hasIm(lhstype) && hasRe(rhstype)) 262 if(lhs_im && rhs_re)
277 imre = gIR->ir->CreateMul(lhs_im, rhs_re, "imre_mul"); 263 imre = gIR->ir->CreateMul(lhs_im, rhs_re, "imre_mul");
278 if(hasIm(lhstype) && hasIm(rhstype)) 264 if(lhs_im && rhs_im)
279 imim = gIR->ir->CreateMul(lhs_im, rhs_im, "imim_mul"); 265 imim = gIR->ir->CreateMul(lhs_im, rhs_im, "imim_mul");
280 266
281 if(rere && imim) 267 if(rere && imim)
282 res_re = gIR->ir->CreateSub(rere, imim, "rere_imim_sub"); 268 res_re = gIR->ir->CreateSub(rere, imim, "rere_imim_sub");
283 else if(rere) 269 else if(rere)
284 res_re = rere; 270 res_re = rere;
285 else if(imim) 271 else if(imim)
286 res_re = gIR->ir->CreateNeg(imim, "imim_neg"); 272 res_re = gIR->ir->CreateNeg(imim, "imim_neg");
287 else 273 else
288 res_re = hasRe(lhstype) ? rhs_re : lhs_re; // null! 274 res_re = lhs_re ? rhs_re : lhs_re; // null!
289 275
290 if(reim && imre) 276 if(reim && imre)
291 res_im = gIR->ir->CreateAdd(reim, imre, "reim_imre_add"); 277 res_im = gIR->ir->CreateAdd(reim, imre, "reim_imre_add");
292 else if(reim) 278 else if(reim)
293 res_im = reim; 279 res_im = reim;
294 else if(imre) 280 else if(imre)
295 res_im = imre; 281 res_im = imre;
296 else 282 else
297 res_im = hasRe(lhstype) ? rhs_im : lhs_re; // null! 283 res_im = lhs_re ? rhs_im : lhs_re; // null!
298 284
299 LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im); 285 LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im);
300 return new DImValue(type, res); 286 return new DImValue(type, res);
301 } 287 }
302 288
303 ////////////////////////////////////////////////////////////////////////////////////////// 289 //////////////////////////////////////////////////////////////////////////////////////////
304 290
305 DValue* DtoComplexDiv(Loc& loc, Type* type, DValue* lhs, DValue* rhs) 291 DValue* DtoComplexDiv(Loc& loc, Type* type, DValue* lhs, DValue* rhs)
306 { 292 {
307 DValue* clhs = DtoComplex(loc, type, resolveLR(lhs, true));
308 DValue* crhs = DtoComplex(loc, type, resolveLR(rhs, false));
309
310 llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im; 293 llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;
311 294
312 // lhs values 295 // lhs values
313 DtoGetComplexParts(clhs, lhs_re, lhs_im); 296 DtoGetComplexParts(loc, type, lhs, lhs_re, lhs_im);
314 // rhs values 297 // rhs values
315 DtoGetComplexParts(crhs, rhs_re, rhs_im); 298 DtoGetComplexParts(loc, type, rhs, rhs_re, rhs_im);
316
317 Type* lhstype = lhs->getType();
318 Type* rhstype = rhs->getType();
319 299
320 // if divisor is only real, division is simple 300 // if divisor is only real, division is simple
321 if(hasRe(rhstype) && !hasIm(rhstype)) { 301 if(rhs_re && !rhs_im) {
322 if(hasRe(lhstype)) 302 if(lhs_re)
323 res_re = gIR->ir->CreateFDiv(lhs_re, rhs_re, "re_divby_re"); 303 res_re = gIR->ir->CreateFDiv(lhs_re, rhs_re, "re_divby_re");
324 else 304 else
325 res_re = lhs_re; 305 res_re = lhs_re;
326 if(hasIm(lhstype)) 306 if(lhs_im)
327 res_im = gIR->ir->CreateFDiv(lhs_im, rhs_re, "im_divby_re"); 307 res_im = gIR->ir->CreateFDiv(lhs_im, rhs_re, "im_divby_re");
328 else 308 else
329 res_im = lhs_im; 309 res_im = lhs_im;
330 } 310 }
331 // if divisor is only imaginary, division is simple too 311 // if divisor is only imaginary, division is simple too
332 else if(!hasRe(rhstype) && hasIm(rhstype)) { 312 else if(!rhs_re && rhs_im) {
333 if(hasRe(lhstype)) 313 if(lhs_re)
334 res_im = gIR->ir->CreateNeg(gIR->ir->CreateFDiv(lhs_re, rhs_im, "re_divby_im"), "neg"); 314 res_im = gIR->ir->CreateNeg(gIR->ir->CreateFDiv(lhs_re, rhs_im, "re_divby_im"), "neg");
335 else 315 else
336 res_im = lhs_re; 316 res_im = lhs_re;
337 if(hasIm(lhstype)) 317 if(lhs_im)
338 res_re = gIR->ir->CreateFDiv(lhs_im, rhs_im, "im_divby_im"); 318 res_re = gIR->ir->CreateFDiv(lhs_im, rhs_im, "im_divby_im");
339 else 319 else
340 res_re = lhs_im; 320 res_re = lhs_im;
341 } 321 }
342 // full division 322 // full division
343 else { 323 else {
344 llvm::Value *tmp1, *tmp2, *denom; 324 llvm::Value *tmp1, *tmp2, *denom;
345 325
346 if(hasRe(lhstype) && hasIm(lhstype)) { 326 if(lhs_re && lhs_im) {
347 tmp1 = gIR->ir->CreateMul(lhs_re, rhs_re, "rere"); 327 tmp1 = gIR->ir->CreateMul(lhs_re, rhs_re, "rere");
348 tmp2 = gIR->ir->CreateMul(lhs_im, rhs_im, "imim"); 328 tmp2 = gIR->ir->CreateMul(lhs_im, rhs_im, "imim");
349 res_re = gIR->ir->CreateAdd(tmp1, tmp2, "rere_plus_imim"); 329 res_re = gIR->ir->CreateAdd(tmp1, tmp2, "rere_plus_imim");
350 330
351 tmp1 = gIR->ir->CreateMul(lhs_re, rhs_im, "reim"); 331 tmp1 = gIR->ir->CreateMul(lhs_re, rhs_im, "reim");
352 tmp2 = gIR->ir->CreateMul(lhs_im, rhs_re, "imre"); 332 tmp2 = gIR->ir->CreateMul(lhs_im, rhs_re, "imre");
353 res_im = gIR->ir->CreateSub(tmp2, tmp1, "imre_sub_reim"); 333 res_im = gIR->ir->CreateSub(tmp2, tmp1, "imre_sub_reim");
354 } 334 }
355 else if(hasRe(lhstype)) { 335 else if(lhs_re) {
356 res_re = gIR->ir->CreateMul(lhs_re, rhs_re, "rere"); 336 res_re = gIR->ir->CreateMul(lhs_re, rhs_re, "rere");
357 337
358 res_im = gIR->ir->CreateMul(lhs_re, rhs_im, "reim"); 338 res_im = gIR->ir->CreateMul(lhs_re, rhs_im, "reim");
359 res_im = gIR->ir->CreateNeg(res_im); 339 res_im = gIR->ir->CreateNeg(res_im);
360 } 340 }
361 else if(hasIm(lhstype)) { 341 else if(lhs_im) {
362 res_re = gIR->ir->CreateMul(lhs_im, rhs_im, "imim"); 342 res_re = gIR->ir->CreateMul(lhs_im, rhs_im, "imim");
363 res_im = gIR->ir->CreateMul(lhs_im, rhs_re, "imre"); 343 res_im = gIR->ir->CreateMul(lhs_im, rhs_re, "imre");
364 } 344 }
365 else 345 else
366 assert(0 && "lhs has neither real nor imaginary part"); 346 assert(0 && "lhs has neither real nor imaginary part");
379 359
380 ////////////////////////////////////////////////////////////////////////////////////////// 360 //////////////////////////////////////////////////////////////////////////////////////////
381 361
382 DValue* DtoComplexNeg(Loc& loc, Type* type, DValue* val) 362 DValue* DtoComplexNeg(Loc& loc, Type* type, DValue* val)
383 { 363 {
384 val = DtoComplex(loc, type, resolveLR(val, false));
385
386 llvm::Value *a, *b, *re, *im; 364 llvm::Value *a, *b, *re, *im;
387 365
388 // values 366 // values
389 DtoGetComplexParts(val, a, b); 367 DtoGetComplexParts(loc, type, val, a, b);
390 368
391 // sub up 369 // neg up
370 assert(a && b);
392 re = gIR->ir->CreateNeg(a, "tmp"); 371 re = gIR->ir->CreateNeg(a, "tmp");
393 im = gIR->ir->CreateNeg(b, "tmp"); 372 im = gIR->ir->CreateNeg(b, "tmp");
394 373
395 LLValue* res = DtoAggrPair(DtoType(type), re, im); 374 LLValue* res = DtoAggrPair(DtoType(type), re, im);
396 return new DImValue(type, res); 375 return new DImValue(type, res);
400 379
401 LLValue* DtoComplexEquals(Loc& loc, TOK op, DValue* lhs, DValue* rhs) 380 LLValue* DtoComplexEquals(Loc& loc, TOK op, DValue* lhs, DValue* rhs)
402 { 381 {
403 Type* type = lhs->getType(); 382 Type* type = lhs->getType();
404 383
405 lhs = DtoComplex(loc, type, resolveLR(lhs, false)); 384 llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;
406 rhs = DtoComplex(loc, type, resolveLR(rhs, false));
407
408 llvm::Value *a, *b, *c, *d;
409 385
410 // lhs values 386 // lhs values
411 DtoGetComplexParts(lhs, a, b); 387 DtoGetComplexParts(loc, type, lhs, lhs_re, lhs_im);
412 // rhs values 388 // rhs values
413 DtoGetComplexParts(rhs, c, d); 389 DtoGetComplexParts(loc, type, rhs, rhs_re, rhs_im);
414 390
415 // select predicate 391 // select predicate
416 llvm::FCmpInst::Predicate cmpop; 392 llvm::FCmpInst::Predicate cmpop;
417 if (op == TOKequal) 393 if (op == TOKequal)
418 cmpop = llvm::FCmpInst::FCMP_OEQ; 394 cmpop = llvm::FCmpInst::FCMP_OEQ;
419 else 395 else
420 cmpop = llvm::FCmpInst::FCMP_UNE; 396 cmpop = llvm::FCmpInst::FCMP_UNE;
421 397
422 // (l.re==r.re && l.im==r.im) or (l.re!=r.re || l.im!=r.im) 398 // (l.re==r.re && l.im==r.im) or (l.re!=r.re || l.im!=r.im)
423 LLValue* b1 = new llvm::FCmpInst(cmpop, a, c, "tmp", gIR->scopebb()); 399 LLValue* b1 = new llvm::FCmpInst(cmpop, lhs_re, rhs_re, "tmp", gIR->scopebb());
424 LLValue* b2 = new llvm::FCmpInst(cmpop, b, d, "tmp", gIR->scopebb()); 400 LLValue* b2 = new llvm::FCmpInst(cmpop, lhs_im, rhs_im, "tmp", gIR->scopebb());
425 401
426 if (op == TOKequal) 402 if (op == TOKequal)
427 return gIR->ir->CreateAnd(b1,b2,"tmp"); 403 return gIR->ir->CreateAnd(b1,b2,"tmp");
428 else 404 else
429 return gIR->ir->CreateOr(b1,b2,"tmp"); 405 return gIR->ir->CreateOr(b1,b2,"tmp");
438 if (to->iscomplex()) { 414 if (to->iscomplex()) {
439 if (vty->size() == to->size()) 415 if (vty->size() == to->size())
440 return val; 416 return val;
441 417
442 llvm::Value *re, *im; 418 llvm::Value *re, *im;
443 DtoGetComplexParts(val, re, im); 419 DtoGetComplexParts(loc, val->getType(), val, re, im);
444 const LLType* toty = DtoComplexBaseType(to); 420 const LLType* toty = DtoComplexBaseType(to);
445 421
446 if (to->size() < vty->size()) { 422 if (to->size() < vty->size()) {
447 re = gIR->ir->CreateFPTrunc(re, toty, "tmp"); 423 re = gIR->ir->CreateFPTrunc(re, toty, "tmp");
448 im = gIR->ir->CreateFPTrunc(im, toty, "tmp"); 424 im = gIR->ir->CreateFPTrunc(im, toty, "tmp");