23
23
24
24
using namespace llvm ;
25
25
26
+ // / Generate code to compute the remainder of two signed integers. Returns the
27
+ // / remainder, which will have the sign of the dividend. Builder's insert point
28
+ // / should be pointing where the caller wants code generated, e.g. at the srem
29
+ // / instruction. This will generate a urem in the process, and Builder's insert
30
+ // / point will be pointing at the uren (if present, i.e. not folded), ready to
31
+ // / be expanded if the user wishes
32
+ static Value *generateSignedRemainderCode (Value *Dividend, Value *Divisor,
33
+ IRBuilder<> &Builder) {
34
+ ConstantInt *ThirtyOne = Builder.getInt32 (31 );
35
+
36
+ // ; %dividend_sgn = ashr i32 %dividend, 31
37
+ // ; %divisor_sgn = ashr i32 %divisor, 31
38
+ // ; %dvd_xor = xor i32 %dividend, %dividend_sgn
39
+ // ; %dvs_xor = xor i32 %divisor, %divisor_sgn
40
+ // ; %u_dividend = sub i32 %dvd_xor, %dividend_sgn
41
+ // ; %u_divisor = sub i32 %dvs_xor, %divisor_sgn
42
+ // ; %urem = urem i32 %dividend, %divisor
43
+ // ; %xored = xor i32 %urem, %dividend_sgn
44
+ // ; %srem = sub i32 %xored, %dividend_sgn
45
+ Value *DividendSign = Builder.CreateAShr (Dividend, ThirtyOne);
46
+ Value *DivisorSign = Builder.CreateAShr (Divisor, ThirtyOne);
47
+ Value *DvdXor = Builder.CreateXor (Dividend, DividendSign);
48
+ Value *DvsXor = Builder.CreateXor (Divisor, DivisorSign);
49
+ Value *UDividend = Builder.CreateSub (DvdXor, DividendSign);
50
+ Value *UDivisor = Builder.CreateSub (DvsXor, DivisorSign);
51
+ Value *URem = Builder.CreateURem (UDividend, UDivisor);
52
+ Value *Xored = Builder.CreateXor (URem, DividendSign);
53
+ Value *SRem = Builder.CreateSub (Xored, DividendSign);
54
+
55
+ if (Instruction *URem = dyn_cast<Instruction>(URem))
56
+ Builder.SetInsertPoint (URem);
57
+
58
+ return SRem;
59
+ }
60
+
61
+
62
+ // / Generate code to compute the remainder of two unsigned integers. Returns the
63
+ // / remainder. Builder's insert point should be pointing where the caller wants
64
+ // / code generated, e.g. at the urem instruction. This will generate a udiv in
65
+ // / the process, and Builder's insert point will be pointing at the udiv (if
66
+ // / present, i.e. not folded), ready to be expanded if the user wishes
67
+ static Value *generatedUnsignedRemainderCode (Value *Dividend, Value *Divisor,
68
+ IRBuilder<> &Builder) {
69
+ // Remainder = Dividend - Quotient*Divisor
70
+
71
+ // ; %quotient = udiv i32 %dividend, %divisor
72
+ // ; %product = mul i32 %divisor, %quotient
73
+ // ; %remainder = sub i32 %dividend, %product
74
+ Value *Quotient = Builder.CreateUDiv (Dividend, Divisor);
75
+ Value *Product = Builder.CreateMul (Divisor, Quotient);
76
+ Value *Remainder = Builder.CreateSub (Dividend, Product);
77
+
78
+ if (Instruction *UDiv = dyn_cast<Instruction>(Quotient))
79
+ Builder.SetInsertPoint (UDiv);
80
+
81
+ return Remainder;
82
+ }
83
+
26
84
// / Generate code to divide two signed integers. Returns the quotient, rounded
27
- // / towards 0. Builder's insert point should be pointing at the sdiv
28
- // / instruction. This will generate a udiv in the process, and Builder's insert
29
- // / point will be pointing at the udiv (if present, i.e. not folded), ready to
30
- // / be expanded if the user wishes.
85
+ // / towards 0. Builder's insert point should be pointing where the caller wants
86
+ // / code generated, e.g. at the sdiv instruction. This will generate a udiv in
87
+ // / the process, and Builder's insert point will be pointing at the udiv (if
88
+ // / present, i.e. not folded), ready to be expanded if the user wishes.
31
89
static Value *generateSignedDivisionCode (Value *Dividend, Value *Divisor,
32
90
IRBuilder<> &Builder) {
33
91
// Implementation taken from compiler-rt's __divsi3
@@ -62,8 +120,8 @@ static Value *generateSignedDivisionCode(Value *Dividend, Value *Divisor,
62
120
}
63
121
64
122
// / Generates code to divide two unsigned scalar 32-bit integers. Returns the
65
- // / quotient, rounded towards 0. Builder's insert point should be pointing at
66
- // / the udiv instruction.
123
+ // / quotient, rounded towards 0. Builder's insert point should be pointing where
124
+ // / the caller wants code generated, e.g. at the udiv instruction.
67
125
static Value *generateUnsignedDivisionCode (Value *Dividend, Value *Divisor,
68
126
IRBuilder<> &Builder) {
69
127
// The basic algorithm can be found in the compiler-rt project's
@@ -265,6 +323,56 @@ static Value *generateUnsignedDivisionCode(Value *Dividend, Value *Divisor,
265
323
return Q_5;
266
324
}
267
325
326
+ // / Generate code to calculate the remainder of two integers, replacing Rem with
327
+ // / the generated code. This currently generates code using the udiv expansion,
328
+ // / but future work includes generating more specialized code, e.g. when more
329
+ // / information about the operands are known. Currently only implements 32bit
330
+ // / scalar division (due to udiv's limitation), but future work is removing this
331
+ // / limitation.
332
+ // /
333
+ // / @brief Replace Rem with generated code.
334
+ bool llvm::expandRemainder (BinaryOperator *Rem) {
335
+ assert ((Rem->getOpcode () == Instruction::SRem ||
336
+ Rem->getOpcode () == Instruction::URem) &&
337
+ " Trying to expand remainder from a non-remainder function" );
338
+
339
+ IRBuilder<> Builder (Rem);
340
+
341
+ // First prepare the sign if it's a signed remainder
342
+ if (Rem->getOpcode () == Instruction::SRem) {
343
+ Value *Remainder = generateSignedRemainderCode (Rem->getOperand (0 ),
344
+ Rem->getOperand (1 ), Builder);
345
+
346
+ Rem->replaceAllUsesWith (Remainder);
347
+ Rem->dropAllReferences ();
348
+ Rem->eraseFromParent ();
349
+
350
+ // If we didn't actually generate a udiv instruction, we're done
351
+ BinaryOperator *BO = dyn_cast<BinaryOperator>(Builder.GetInsertPoint ());
352
+ if (!BO || BO->getOpcode () != Instruction::URem)
353
+ return true ;
354
+
355
+ Rem = BO;
356
+ }
357
+
358
+ Value *Remainder = generatedUnsignedRemainderCode (Rem->getOperand (0 ),
359
+ Rem->getOperand (1 ),
360
+ Builder);
361
+
362
+ Rem->replaceAllUsesWith (Remainder);
363
+ Rem->dropAllReferences ();
364
+ Rem->eraseFromParent ();
365
+
366
+ // Expand the udiv
367
+ if (BinaryOperator *UDiv = dyn_cast<BinaryOperator>(Builder.GetInsertPoint ())) {
368
+ assert (UDiv->getOpcode () == Instruction::UDiv && " Non-udiv in expansion?" );
369
+ expandDivision (UDiv);
370
+ }
371
+
372
+ return true ;
373
+ }
374
+
375
+
268
376
// / Generate code to divide two integers, replacing Div with the generated
269
377
// / code. This currently generates code similarly to compiler-rt's
270
378
// / implementations, but future work includes generating more specialized code
@@ -287,7 +395,7 @@ bool llvm::expandDivision(BinaryOperator *Div) {
287
395
if (Div->getOpcode () == Instruction::SDiv) {
288
396
// Lower the code to unsigned division, and reset Div to point to the udiv.
289
397
Value *Quotient = generateSignedDivisionCode (Div->getOperand (0 ),
290
- Div->getOperand (1 ), Builder);
398
+ Div->getOperand (1 ), Builder);
291
399
Div->replaceAllUsesWith (Quotient);
292
400
Div->dropAllReferences ();
293
401
Div->eraseFromParent ();
0 commit comments