(HiReg (S2_asl_r_p (Combinew $Rs, $Rt), $Ru))>;
def FShl64i: OutPatFrag<(ops node:$Rs, node:$Rt, node:$S),
- (S2_lsr_i_p_or (S2_asl_i_p $Rt, $S), $Rs, (Subi<64> $S))>;
+ (S2_lsr_i_p_or (S2_asl_i_p $Rs, $S), $Rt, (Subi<64> $S))>;
def FShl64r: OutPatFrag<(ops node:$Rs, node:$Rt, node:$Ru),
- (S2_lsr_r_p_or (S2_asl_r_p $Rt, $Ru), $Rs, (A2_subri 64, $Ru))>;
+ (S2_lsr_r_p_or (S2_asl_r_p $Rs, $Ru), $Rt, (A2_subri 64, $Ru))>;
// Combined SDNodeXForm: (Divu8 (Subi<64> $S))
def Divu64_8: SDNodeXForm<imm, [{
}
; CHECK-LABEL: f2:
-; CHECK: r[[R20:[0-9]+]]:[[R21:[0-9]+]] = asl(r3:2,#17)
-; CHECK: r[[R20]]:[[R21]] |= lsr(r1:0,#47)
+; CHECK: r[[R20:[0-9]+]]:[[R21:[0-9]+]] = asl(r1:0,#17)
+; CHECK: r[[R20]]:[[R21]] |= lsr(r3:2,#47)
define i64 @f2(i64 %a0, i64 %a1) #1 {
b0:
%v0 = tail call i64 @llvm.fshl.i64(i64 %a0, i64 %a1, i64 17)
}
; CHECK-LABEL: f3:
-; CHECK: r[[R30:[0-9]+]]:[[R31:[0-9]+]] = asl(r3:2,r4)
+; CHECK: r[[R30:[0-9]+]]:[[R31:[0-9]+]] = asl(r1:0,r4)
; CHECK: r[[R32:[0-9]+]] = sub(#64,r4)
-; CHECK: r[[R30]]:[[R31]] |= lsr(r1:0,r[[R32]])
+; CHECK: r[[R30]]:[[R31]] |= lsr(r3:2,r[[R32]])
define i64 @f3(i64 %a0, i64 %a1, i64 %a2) #1 {
b0:
%v0 = tail call i64 @llvm.fshl.i64(i64 %a0, i64 %a1, i64 %a2)
--- /dev/null
+; RUN: llc -mtriple=hexagon < %s | FileCheck %s
+
+; This patch corrects the order of operands in the pattern that lowers funnel
+; shift-left.
+
+; CHECK: r[[R17:[0-9]+]]:[[R16:[0-9]+]] = combine
+; CHECK: call parity
+; CHECK: r[[R1:[0-9]+]]:[[R0:[0-9]+]] = asl(r[[R1]]:[[R0]],#63)
+; CHECK: r[[R1]]:[[R0]] |= lsr(r[[R17]]:[[R16]],#1)
+
+target triple = "hexagon-unknown-unknown-elf"
+
+define dso_local i64 @fshl(i64 %x, i64 %y) {
+entry:
+ %x.addr = alloca i64, align 8
+ %y.addr = alloca i64, align 8
+ store i64 %x, i64* %x.addr, align 8
+ store i64 %y, i64* %y.addr, align 8
+ %0 = load i64, i64* %x.addr, align 8
+ %shr = lshr i64 %0, 1
+ %1 = load i64, i64* %x.addr, align 8
+ %2 = load i64, i64* %y.addr, align 8
+ %call = call i64 @parity(i64 %1, i64 %2)
+ %shl = shl i64 %call, 63
+ %or = or i64 %shr, %shl
+ store i64 %or, i64* %x.addr, align 8
+ %3 = load i64, i64* %x.addr, align 8
+ ret i64 %3
+}
+
+declare dso_local i64 @parity(i64, i64)