<div dir="ltr"><div class="gmail_quote"><div dir="ltr">Problem code:<div><div>bool fits_shifter(uint32_t imm32,</div><div>                         uint32_t* rotate_imm,</div><div>                         uint32_t* immed_8,</div><div>                         Instr* instr) {</div><div>  // imm32 must be unsigned.</div><div>  for (int rot = 0; rot < 16; rot++) {</div><div>    uint32_t imm8 = (imm32 << 2*rot) | (imm32 >> (32 - 2*rot));</div><div>    if ((imm8 <= 0xff)) {</div><div>      *rotate_imm = rot;</div><div>      *immed_8 = imm8;</div><div>      return true;</div><div>    }</div><div>  }</div><div>  return false;</div><div>}</div></div><div><br></div><div>After loop unroll pass, which has never been enabled before 3.8, the llvm IR:</div><div><div>for.body:                                         ; preds = %tailrecurse</div><div>  br i1 false, label %cleanup3, label %for.inc</div><div><br></div><div>for.inc:                                          ; preds = %for.body</div><div>  %shl.1 = shl i32 %<a href="http://imm32.tr" target="_blank">imm32.tr</a>, 2</div><div>  %shr.1 = lshr i32 %<a href="http://imm32.tr" target="_blank">imm32.tr</a>, 30</div><div>  %or.1 = or i32 %shr.1, %shl.1</div><div>  %cmp2.1 = icmp ult i32 %or.1, 256</div><div>  br i1 %cmp2.1, label %cleanup3, label %for.inc.1</div></div><div><br></div><div>As you see, the for.body block becomes a trivial block, which</div><div>is caused by instruction simplify, like the following:</div><div><br></div><div><div>for.body:                                         ; preds = %tailrecurse</div><div>  %mul = shl nsw i32 0, 1</div><div>  %shl = shl i32 %<a href="http://imm32.tr" target="_blank">imm32.tr</a>, %mul</div><div>  %sub = sub nuw nsw i32 32, %mul</div><div>  %shr = lshr i32 %<a href="http://imm32.tr" target="_blank">imm32.tr</a>, %sub</div><div>  %or = or i32 %shr, %shl</div><div>  %cmp2 = icmp ult i32 %or, 256</div><div>  br i1 %cmp2, label %cleanup3, label %for.inc</div></div><div><br></div><div><br></div><div>When simplifying  %shr = lshr i32 %<a href="http://imm32.tr" target="_blank">imm32.tr</a>, %sub with %sub is a constant 32,<br></div><div>the value undefined will be generated. Then %or = or i32 %shr, %shl will generate a</div><div>constant -1, and then cause the whole block trivially branch to the negative branch.</div><div><br></div><div>My patch in the attachment tries to fix this by generating constant 0 when the right shift exceeds</div><div>the types bit limits. And That's what is expecting in the real life scenario. </div></div>
</div><br></div>