We’ve recently moved our project from LLVM 3.6 to LLVM 3.9. I noticed one of our code generation tests is breaking in 3.9.
The test is:
; RUN: llc < %s -march=xstg | FileCheck %s
define i64 @bclr64(i64 %a, i64 %b) nounwind readnone {
entry:
; CHECK: bclr r1, r0, r1, 64
%sub = sub i64 %b, 1
%shl = shl i64 1, %sub
%xor = xor i64 %shl, -1
%and = and i64 %a, %xor
ret i64 %and
}
I ran llc with -debug to get a better idea of what’s going on and found:
Initial selection DAG: BB#0 ‘bclr64:entry’
SelectionDAG has 14 nodes:
t0: ch = EntryToken
t2: i64,ch = CopyFromReg t0, Register:i64 %vreg0
t4: i64,ch = CopyFromReg t0, Register:i64 %vreg1
t6: i64 = sub t4, Constant:i64<1>
t7: i64 = shl Constant:i64<1>, t6
t9: i64 = xor t7, Constant:i64<-1>
t10: i64 = and t2, t9
t12: ch,glue = CopyToReg t0, Register:i64 %R1, t10
t13: ch = XSTGISD::Ret t12, Register:i64 %R1, t12:1
Combining: t13: ch = XSTGISD::Ret t12, Register:i64 %R1, t12:1
Combining: t12: ch,glue = CopyToReg t0, Register:i64 %R1, t10
Combining: t11: i64 = Register %R1
Combining: t10: i64 = and t2, t9
Combining: t9: i64 = xor t7, Constant:i64<-1>
… into: t15: i64 = rotl Constant:i64<-2>, t6
Combining: t10: i64 = and t2, t15
Combining: t15: i64 = rotl Constant:i64<-2>, t6
Combining: t14: i64 = Constant<-2>
Combining: t6: i64 = sub t4, Constant:i64<1>
… into: t17: i64 = add t4, Constant:i64<-1>
Combining: t15: i64 = rotl Constant:i64<-2>, t17
These rotl instructions weren’t showing up when I ran llc 3.6 and that’s completely changing the generated code at the end which means the test fails (and it’s less optimal than it was in 3.6).
I’ve been looking in the LLVM language docs (3.9 version) and I don’t see any documentation on ‘rotl’. What does it do? Why isn’t it in the docs?
Phil