<div>I've just revised the current LLVM trunk.</div><div><br></div>>><meta http-equiv="content-type" content="text/html; charset=utf-8">Adding separate "s" instructions is not the right thing to do. šWe've been trying hard to avoid adding those "twins". šThe instructions that can optionally set the condition >>codes have an "optional def" operand. šFor example, look at the "cc_out" operand in the "sI" class defined in ARMInstrFormats.td. šIf that operand is set to the CPSR >>register, then the instruction becomes the "s" variant.<div>

<br></div><div>Alright, but everything is not so shiny as one may expect. For example, when I set "mov" instruction to define CPSR, generated assembler is still "mov", not "movs". "movs" is absolutely correct instruction which sets CPSR.šThe same operation on "add" brings the desired effect. So, if one should go the way you propose instead of adding separate instructions to tablegen, what he or she has to modify in LLVM code to resolve such issues? There are lots of similar instructions unsupported by LLVM which SURE HAVE a suffixed twin.</div>

<div><br>>><meta http-equiv="content-type" content="text/html; charset=utf-8">There are some existing peephole optimizations to make use of this, but there are some unresolved issues as well. šDo you have some example testcases that show where >>we're missing opportunities?</div>

<div><br></div><div>Oh yeah. Consider the following existing peephole optimization:</div><div>PeepholeOptimizer.cpp->PeepholeOptimizer::OptimizeCmpInstr->ARMBaseInstrInfo::OptimizeCompareInstr.</div><div><br></div>
<div>
<div>ššcase ARM::ADDri:</div><div>ššcase ARM::ANDri:</div><div>ššcase ARM::t2ANDri:</div><div>ššcase ARM::SUBri:</div><div>ššcase ARM::t2ADDri:</div><div>ššcase ARM::t2SUBri:</div></div><div><div>šš š// Toggle the optional operand to CPSR.</div>

<div>šš šMI->getOperand(5).setReg(ARM::CPSR);</div><div>šš šMI->getOperand(5).setIsDef(true);</div><div>šš šCmpInstr->eraseFromParent();</div><div>šš šreturn true;</div></div><div><br></div><div>...and that's all,šhoweveršthis switch should be giant (88 instructions instead of 6 can be supported so far). Yet another question unclear to me is what the origin of the comment above</div>

<div><br></div><div>// Set the "zero" bit in CPSR.</div><div><br></div><div>is. Why not also "negative"?</div><div>Moreover, that peephole thingšparticularlyšcan be dramatically improved with some advanced analysis.</div>

<div>For example, consider the following program:</div><div><br></div><div><div>#include <stdio.h></div><div><br></div><div>int main()</div><div>{</div><div>šš šsrand(time(NULL));</div><div>šš šint x, y;</div><div>
šš šx = rand();</div>
<div>šš šy = rand();</div><div>šš šint z = x * y;</div><div>šš šif (z == 0)</div><div>šš š{</div><div>šš š<span class="Apple-tab-span" style="white-space:pre"> </span>printf("Zero");</div><div>šš š}</div><div>šš šz = x|y;</div>

<div>šš šif (z > 0)</div><div>šš š{</div><div>šš š<span class="Apple-tab-span" style="white-space:pre">      </span>printf("Greater");</div><div>šš š}</div><div>šš šelse</div><div>šš š{</div><div>šš š<span class="Apple-tab-span" style="white-space:pre">      </span>printf("Smaller");</div>

<div>šš š}</div><div><span class="Apple-tab-span" style="white-space:pre">  </span>return 0;</div><div>}</div></div><div><br></div><div>It compiles to</div><div><div>.syntax unified</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>.cpu cortex-a8</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>.eabi_attribute 6, 10</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>.eabi_attribute 7, 65</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>.eabi_attribute 8, 1</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>.eabi_attribute 9, 2</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>.eabi_attribute 10, 2</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>.eabi_attribute 20, 1</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>.eabi_attribute 21, 1</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>.eabi_attribute 23, 3</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>.eabi_attribute 24, 1</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>.eabi_attribute 25, 1</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>.file<span class="Apple-tab-span" style="white-space:pre">       </span>"test.bc"</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>.text</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>.globl<span class="Apple-tab-span" style="white-space:pre">      </span>main</div>
<div>
<span class="Apple-tab-span" style="white-space:pre"> </span>.align<span class="Apple-tab-span" style="white-space:pre">      </span>2</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>.type<span class="Apple-tab-span" style="white-space:pre">       </span>main,%function</div>

<div>main: š š š š š š š š š š š š š š š š š @ @main</div><div>@ BB#0: š š š š š š š š š š š š š š š š @ %entry</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>push<span class="Apple-tab-span" style="white-space:pre">        </span>{r4, r5, r11, lr}</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>mov<span class="Apple-tab-span" style="white-space:pre"> </span>r0, #0</div><div><span class="Apple-tab-span" style="white-space:pre">       </span>bl<span class="Apple-tab-span" style="white-space:pre">  </span>time</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>bl<span class="Apple-tab-span" style="white-space:pre">  </span>srand</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>bl<span class="Apple-tab-span" style="white-space:pre">  </span>rand</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>mov<span class="Apple-tab-span" style="white-space:pre"> </span>r4, r0</div><div><span class="Apple-tab-span" style="white-space:pre">       </span>bl<span class="Apple-tab-span" style="white-space:pre">  </span>rand</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>mov<span class="Apple-tab-span" style="white-space:pre"> </span>r5, r0</div><div><span class="Apple-tab-span" style="white-space:pre">       </span>mul<span class="Apple-tab-span" style="white-space:pre"> </span>r0, r5, r4</div>

<div><meta http-equiv="content-type" content="text/html; charset=utf-8">šš š š šcmp<span class="Apple-tab-span" style="white-space: pre; ">   </span>r0, #0</div><div><span class="Apple-tab-span" style="white-space:pre">       </span>bne<span class="Apple-tab-span" style="white-space:pre"> </span>.LBB0_2</div>

<div>@ BB#1: š š š š š š š š š š š š š š š š @ %bb</div><div><span class="Apple-tab-span" style="white-space:pre">  </span>movw<span class="Apple-tab-span" style="white-space:pre">        </span>r0, :lower16:.L.str</div><div><span class="Apple-tab-span" style="white-space:pre">  </span>movt<span class="Apple-tab-span" style="white-space:pre">        </span>r0, :upper16:.L.str</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>bl<span class="Apple-tab-span" style="white-space:pre">  </span>printf</div><div>.LBB0_2: š š š š š š š š š š š š š š š š@ %bb1</div><div><span class="Apple-tab-span" style="white-space:pre">  </span>orr<span class="Apple-tab-span" style="white-space:pre"> </span>r0, r5, r4</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>cmp<span class="Apple-tab-span" style="white-space:pre"> </span>r0, #1</div><div><span class="Apple-tab-span" style="white-space:pre">       </span>blt<span class="Apple-tab-span" style="white-space:pre"> </span>.LBB0_5</div>

<div>@ BB#3: š š š š š š š š š š š š š š š š @ %bb2</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>movw<span class="Apple-tab-span" style="white-space:pre">        </span>r0, :lower16:.L.str1</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>movt<span class="Apple-tab-span" style="white-space:pre">        </span>r0, :upper16:.L.str1</div>

<div>.LBB0_4: š š š š š š š š š š š š š š š š@ %bb2</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>bl<span class="Apple-tab-span" style="white-space:pre">  </span>printf</div><div><span class="Apple-tab-span" style="white-space:pre">       </span>mov<span class="Apple-tab-span" style="white-space:pre"> </span>r0, #0</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>ldmia<span class="Apple-tab-span" style="white-space:pre">       </span>sp!, {r4, r5, r11, pc}</div><div>.LBB0_5: š š š š š š š š š š š š š š š š@ %bb3</div><div>

<span class="Apple-tab-span" style="white-space:pre"> </span>movw<span class="Apple-tab-span" style="white-space:pre">        </span>r0, :lower16:.L.str2</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>movt<span class="Apple-tab-span" style="white-space:pre">        </span>r0, :upper16:.L.str2</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>b<span class="Apple-tab-span" style="white-space:pre">   </span>.LBB0_4</div><div>.Ltmp0:</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>.size<span class="Apple-tab-span" style="white-space:pre">       </span>main, .Ltmp0-main</div>

<div><br></div><div><span class="Apple-tab-span" style="white-space:pre">     </span>.type<span class="Apple-tab-span" style="white-space:pre">       </span>.L.str,%object š š š š š@ @.str</div><div><span class="Apple-tab-span" style="white-space:pre">      </span>.section<span class="Apple-tab-span" style="white-space:pre">    </span>.rodata,"a",%progbits</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>.align<span class="Apple-tab-span" style="white-space:pre">      </span>2</div><div>.L.str:</div><div><span class="Apple-tab-span" style="white-space:pre">      </span>.asciz<span class="Apple-tab-span" style="white-space:pre">      </span> "Zero"</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>.size<span class="Apple-tab-span" style="white-space:pre">       </span>.L.str, 5</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">   </span>.type<span class="Apple-tab-span" style="white-space:pre">       </span>.L.str1,%object š š š š @ @.str1</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>.align<span class="Apple-tab-span" style="white-space:pre">      </span>2</div><div>.L.str1:</div><div><span class="Apple-tab-span" style="white-space:pre">     </span>.asciz<span class="Apple-tab-span" style="white-space:pre">      </span> "Greater"</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>.size<span class="Apple-tab-span" style="white-space:pre">       </span>.L.str1, 8</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">  </span>.type<span class="Apple-tab-span" style="white-space:pre">       </span>.L.str2,%object š š š š @ @.str2</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>.align<span class="Apple-tab-span" style="white-space:pre">      </span>2</div><div>.L.str2:</div><div><span class="Apple-tab-span" style="white-space:pre">     </span>.asciz<span class="Apple-tab-span" style="white-space:pre">      </span> "Smaller"</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>.size<span class="Apple-tab-span" style="white-space:pre">       </span>.L.str2, 8</div></div><meta http-equiv="content-type" content="text/html; charset=utf-8"><div>

<br></div><div>At the same time, my optimization produces</div><div><br></div><div><div><span class="Apple-tab-span" style="white-space:pre">   </span>.syntax unified</div><div><span class="Apple-tab-span" style="white-space:pre">      </span>.cpu cortex-a8</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>.eabi_attribute 6, 10</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>.eabi_attribute 7, 65</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>.eabi_attribute 8, 1</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>.eabi_attribute 9, 2</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>.eabi_attribute 10, 2</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>.eabi_attribute 20, 1</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>.eabi_attribute 21, 1</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>.eabi_attribute 23, 3</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>.eabi_attribute 24, 1</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>.eabi_attribute 25, 1</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>.file<span class="Apple-tab-span" style="white-space:pre">       </span>"test.bc"</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>.text</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>.globl<span class="Apple-tab-span" style="white-space:pre">      </span>main</div>
<div>
<span class="Apple-tab-span" style="white-space:pre"> </span>.align<span class="Apple-tab-span" style="white-space:pre">      </span>2</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>.type<span class="Apple-tab-span" style="white-space:pre">       </span>main,%function</div>

<div>main: š š š š š š š š š š š š š š š š š @ @main</div><div>@ BB#0: š š š š š š š š š š š š š š š š @ %entry</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>push<span class="Apple-tab-span" style="white-space:pre">        </span>{r4, r5, r11, lr}</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>mov<span class="Apple-tab-span" style="white-space:pre"> </span>r0, #0</div><div><span class="Apple-tab-span" style="white-space:pre">       </span>bl<span class="Apple-tab-span" style="white-space:pre">  </span>time</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>bl<span class="Apple-tab-span" style="white-space:pre">  </span>srand</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>bl<span class="Apple-tab-span" style="white-space:pre">  </span>rand</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>mov<span class="Apple-tab-span" style="white-space:pre"> </span>r4, r0</div><div><span class="Apple-tab-span" style="white-space:pre">       </span>bl<span class="Apple-tab-span" style="white-space:pre">  </span>rand</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>mov<span class="Apple-tab-span" style="white-space:pre"> </span>r5, r0</div><div><span class="Apple-tab-span" style="white-space:pre">       </span>muls<span class="Apple-tab-span" style="white-space:pre">        </span>r0, r5, r4</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>bne<span class="Apple-tab-span" style="white-space:pre"> </span>.LBB0_2</div><div>@ BB#1: š š š š š š š š š š š š š š š š @ %bb</div><div><span class="Apple-tab-span" style="white-space:pre">  </span>movw<span class="Apple-tab-span" style="white-space:pre">        </span>r0, :lower16:.L.str</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>movt<span class="Apple-tab-span" style="white-space:pre">        </span>r0, :upper16:.L.str</div><div><span class="Apple-tab-span" style="white-space:pre">  </span>bl<span class="Apple-tab-span" style="white-space:pre">  </span>printf</div>

<div>.LBB0_2: š š š š š š š š š š š š š š š š@ %bb1</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>orrs<span class="Apple-tab-span" style="white-space:pre">        </span>r0, r5, r4</div><div><span class="Apple-tab-span" style="white-space:pre">   </span>ble<span class="Apple-tab-span" style="white-space:pre"> </span>.LBB0_5</div>

<div>@ BB#3: š š š š š š š š š š š š š š š š @ %bb2</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>movw<span class="Apple-tab-span" style="white-space:pre">        </span>r0, :lower16:.L.str1</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>movt<span class="Apple-tab-span" style="white-space:pre">        </span>r0, :upper16:.L.str1</div>

<div>.LBB0_4: š š š š š š š š š š š š š š š š@ %bb2</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>bl<span class="Apple-tab-span" style="white-space:pre">  </span>printf</div><div><span class="Apple-tab-span" style="white-space:pre">       </span>mov<span class="Apple-tab-span" style="white-space:pre"> </span>r0, #0</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>ldmia<span class="Apple-tab-span" style="white-space:pre">       </span>sp!, {r4, r5, r11, pc}</div><div>.LBB0_5: š š š š š š š š š š š š š š š š@ %bb3</div><div>

<span class="Apple-tab-span" style="white-space:pre"> </span>movw<span class="Apple-tab-span" style="white-space:pre">        </span>r0, :lower16:.L.str2</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>movt<span class="Apple-tab-span" style="white-space:pre">        </span>r0, :upper16:.L.str2</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>b<span class="Apple-tab-span" style="white-space:pre">   </span>.LBB0_4</div><div>.Ltmp0:</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>.size<span class="Apple-tab-span" style="white-space:pre">       </span>main, .Ltmp0-main</div>

<div><br></div><div><span class="Apple-tab-span" style="white-space:pre">     </span>.type<span class="Apple-tab-span" style="white-space:pre">       </span>.L.str,%object š š š š š@ @.str</div><div><span class="Apple-tab-span" style="white-space:pre">      </span>.section<span class="Apple-tab-span" style="white-space:pre">    </span>.rodata,"a",%progbits</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>.align<span class="Apple-tab-span" style="white-space:pre">      </span>2</div><div>.L.str:</div><div><span class="Apple-tab-span" style="white-space:pre">      </span>.asciz<span class="Apple-tab-span" style="white-space:pre">      </span> "Zero"</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>.size<span class="Apple-tab-span" style="white-space:pre">       </span>.L.str, 5</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">   </span>.type<span class="Apple-tab-span" style="white-space:pre">       </span>.L.str1,%object š š š š @ @.str1</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>.align<span class="Apple-tab-span" style="white-space:pre">      </span>2</div><div>.L.str1:</div><div><span class="Apple-tab-span" style="white-space:pre">     </span>.asciz<span class="Apple-tab-span" style="white-space:pre">      </span> "Greater"</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>.size<span class="Apple-tab-span" style="white-space:pre">       </span>.L.str1, 8</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">  </span>.type<span class="Apple-tab-span" style="white-space:pre">       </span>.L.str2,%object š š š š @ @.str2</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>.align<span class="Apple-tab-span" style="white-space:pre">      </span>2</div><div>.L.str2:</div><div><span class="Apple-tab-span" style="white-space:pre">     </span>.asciz<span class="Apple-tab-span" style="white-space:pre">      </span> "Smaller"</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>.size<span class="Apple-tab-span" style="white-space:pre">       </span>.L.str2, 8</div><div><br></div></div><div>You should pay attention to "muls" šinstead of "mul" (lack of support) and "orrs" instead of "orr" (advanced analysis).</div>

<div><br><div class="gmail_quote">18 ฦลืามฬั 2011šว. 21:49 ะฯฬฺุฯืมิลฬุ Bob Wilson <span dir="ltr"><<a href="mailto:bob.wilson@apple.com">bob.wilson@apple.com</a>></span> ฮมะษำมฬ:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

<div class="im"><br>
On Feb 17, 2011, at 10:35 PM, ๗มฤษอ ํมาหฯืรลื wrote:<br>
<br>
> Hello everyone,<br>
><br>
> I've added the "S" suffixed versions of ARM and Thumb2 instructions to tablegen. Those are, for example, "movs" or "muls".<br>
> Of course, some instructions have already had their twins, such as add/adds, and I leaved them untouched.<br>
<br>
</div>Adding separate "s" instructions is not the right thing to do. šWe've been trying hard to avoid adding those "twins". šThe instructions that can optionally set the condition codes have an "optional def" operand. šFor example, look at the "cc_out" operand in the "sI" class defined in ARMInstrFormats.td. šIf that operand is set to the CPSR register, then the instruction becomes the "s" variant.<br>


<br>
There are some existing peephole optimizations to make use of this, but there are some unresolved issues as well. šDo you have some example testcases that show where we're missing opportunities?</blockquote></div><br>

</div>