@@ -313,37 +313,43 @@ static Value *expandAtan2Intrinsic(CallInst *Orig) {
313
313
Value *X = Orig->getOperand (1 );
314
314
Type *Ty = X->getType ();
315
315
IRBuilder<> Builder (Orig);
316
+ Builder.setFastMathFlags (Orig->getFastMathFlags ());
316
317
317
318
Value *Tan = Builder.CreateFDiv (Y, X);
318
319
319
- Value *Atan =
320
+ CallInst *Atan =
320
321
Builder.CreateIntrinsic (Ty, Intrinsic::atan, {Tan}, nullptr , " Elt.Atan" );
322
+ Atan->setTailCall (Orig->isTailCall ());
323
+ Atan->setAttributes (Orig->getAttributes ());
321
324
325
+ // Modify atan result based on https://en.wikipedia.org/wiki/Atan2.
322
326
Constant *Pi = ConstantFP::get (Ty, llvm::numbers::pi);
323
327
Constant *HalfPi = ConstantFP::get (Ty, llvm::numbers::pi / 2 );
324
328
Constant *NegHalfPi = ConstantFP::get (Ty, -llvm::numbers::pi / 2 );
325
329
Constant *Zero = ConstantFP::get (Ty, 0 );
326
-
327
330
Value *AtanAddPi = Builder.CreateFAdd (Atan, Pi);
328
331
Value *AtanSubPi = Builder.CreateFSub (Atan, Pi);
329
332
333
+ // x > 0 -> atan.
330
334
Value *Result = Atan;
331
-
332
335
Value *XLt0 = Builder.CreateFCmpOLT (X, Zero);
333
336
Value *XEq0 = Builder.CreateFCmpOEQ (X, Zero);
334
-
335
337
Value *YGe0 = Builder.CreateFCmpOGE (Y, Zero);
336
338
Value *YLt0 = Builder.CreateFCmpOLT (Y, Zero);
337
339
340
+ // x < 0, y >= 0 -> atan + pi.
338
341
Value *XLt0AndYGe0 = Builder.CreateAnd (XLt0, YGe0);
339
342
Result = Builder.CreateSelect (XLt0AndYGe0, AtanAddPi, Result);
340
343
344
+ // x < 0, y < 0 -> atan - pi.
341
345
Value *XLt0AndYLt0 = Builder.CreateAnd (XLt0, YLt0);
342
346
Result = Builder.CreateSelect (XLt0AndYLt0, AtanSubPi, Result);
343
347
348
+ // x == 0, y < 0 -> -pi/2
344
349
Value *XEq0AndYLt0 = Builder.CreateAnd (XEq0, YLt0);
345
350
Result = Builder.CreateSelect (XEq0AndYLt0, NegHalfPi, Result);
346
351
352
+ // x == 0, y > 0 -> pi/2
347
353
Value *XEq0AndYGe0 = Builder.CreateAnd (XEq0, YGe0);
348
354
Result = Builder.CreateSelect (XEq0AndYGe0, HalfPi, Result);
349
355
0 commit comments