TODO:
* gpr0 allocation
* implement do-loop -> bdnz transform
-* Implement __builtin_trap (ISD::TRAP) as 'tw 31, 0, 0' aka 'trap'.
+* lmw/stmw pass a la arm load store optimizer for prolog/epilog
===-------------------------------------------------------------------------===
Implement Newton-Rhapson method for improving estimate instructions to the
correct accuracy, and implementing divide as multiply by reciprocal when it has
-more than one use. Itanium will want this too.
-
-===-------------------------------------------------------------------------===
-
-Compile this:
-
-int %f1(int %a, int %b) {
- %tmp.1 = and int %a, 15 ; <int> [#uses=1]
- %tmp.3 = and int %b, 240 ; <int> [#uses=1]
- %tmp.4 = or int %tmp.3, %tmp.1 ; <int> [#uses=1]
- ret int %tmp.4
-}
-
-without a copy. We make this currently:
-
-_f1:
- rlwinm r2, r4, 0, 24, 27
- rlwimi r2, r3, 0, 28, 31
- or r3, r2, r2
- blr
-
-The two-addr pass or RA needs to learn when it is profitable to commute an
-instruction to avoid a copy AFTER the 2-addr instruction. The 2-addr pass
-currently only commutes to avoid inserting a copy BEFORE the two addr instr.
+more than one use. Itanium would want this too.
===-------------------------------------------------------------------------===
===-------------------------------------------------------------------------===
+Darwin Stub removal:
+
+We still generate calls to foo$stub, and stubs, on Darwin. This is not
+necessary when building with the Leopard (10.5) or later linker, as stubs are
+generated by ld when necessary. Parameterizing this based on the deployment
+target (-mmacosx-version-min) is probably enough. x86-32 does this right, see
+its logic.
+
+===-------------------------------------------------------------------------===
+
Darwin Stub LICM optimization:
Loops like this:
which is more efficient and can use mfocr. See PR642 for some more context.
//===---------------------------------------------------------------------===//
+
+void foo(float *data, float d) {
+ long i;
+ for (i = 0; i < 8000; i++)
+ data[i] = d;
+}
+void foo2(float *data, float d) {
+ long i;
+ data--;
+ for (i = 0; i < 8000; i++) {
+ data[1] = d;
+ data++;
+ }
+}
+
+These compile to:
+
+_foo:
+ li r2, 0
+LBB1_1: ; bb
+ addi r4, r2, 4
+ stfsx f1, r3, r2
+ cmplwi cr0, r4, 32000
+ mr r2, r4
+ bne cr0, LBB1_1 ; bb
+ blr
+_foo2:
+ li r2, 0
+LBB2_1: ; bb
+ addi r4, r2, 4
+ stfsx f1, r3, r2
+ cmplwi cr0, r4, 32000
+ mr r2, r4
+ bne cr0, LBB2_1 ; bb
+ blr
+
+The 'mr' could be eliminated to folding the add into the cmp better.
+
+//===---------------------------------------------------------------------===//
+Codegen for the following (low-probability) case deteriorated considerably
+when the correctness fixes for unordered comparisons went in (PR 642, 58871).
+It should be possible to recover the code quality described in the comments.
+
+; RUN: llvm-as < %s | llc -march=ppc32 | grep or | count 3
+; This should produce one 'or' or 'cror' instruction per function.
+
+; RUN: llvm-as < %s | llc -march=ppc32 | grep mfcr | count 3
+; PR2964
+
+define i32 @test(double %x, double %y) nounwind {
+entry:
+ %tmp3 = fcmp ole double %x, %y ; <i1> [#uses=1]
+ %tmp345 = zext i1 %tmp3 to i32 ; <i32> [#uses=1]
+ ret i32 %tmp345
+}
+
+define i32 @test2(double %x, double %y) nounwind {
+entry:
+ %tmp3 = fcmp one double %x, %y ; <i1> [#uses=1]
+ %tmp345 = zext i1 %tmp3 to i32 ; <i32> [#uses=1]
+ ret i32 %tmp345
+}
+
+define i32 @test3(double %x, double %y) nounwind {
+entry:
+ %tmp3 = fcmp ugt double %x, %y ; <i1> [#uses=1]
+ %tmp34 = zext i1 %tmp3 to i32 ; <i32> [#uses=1]
+ ret i32 %tmp34
+}
+//===----------------------------------------------------------------------===//
+; RUN: llvm-as < %s | llc -march=ppc32 | not grep fneg
+
+; This could generate FSEL with appropriate flags (FSEL is not IEEE-safe, and
+; should not be generated except with -enable-finite-only-fp-math or the like).
+; With the correctness fixes for PR642 (58871) LowerSELECT_CC would need to
+; recognize a more elaborate tree than a simple SETxx.
+
+define double @test_FNEG_sel(double %A, double %B, double %C) {
+ %D = sub double -0.000000e+00, %A ; <double> [#uses=1]
+ %Cond = fcmp ugt double %D, -0.000000e+00 ; <i1> [#uses=1]
+ %E = select i1 %Cond, double %B, double %C ; <double> [#uses=1]
+ ret double %E
+}
+