<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>