diff --git a/llvm/lib/Target/BPF/BPFISelLowering.h b/llvm/lib/Target/BPF/BPFISelLowering.h index 42707949e864c..d59098f9f569b 100644 --- a/llvm/lib/Target/BPF/BPFISelLowering.h +++ b/llvm/lib/Target/BPF/BPFISelLowering.h @@ -118,7 +118,9 @@ class BPFTargetLowering : public TargetLowering { return Op.size() >= 8 ? MVT::i64 : MVT::i32; } - bool isIntDivCheap(EVT VT, AttributeList Attr) const override { return true; } + bool isIntDivCheap(EVT VT, AttributeList Attr) const override { + return false; + } bool shouldConvertConstantLoadToIntImm(const APInt &Imm, Type *Ty) const override { diff --git a/llvm/test/CodeGen/BPF/32-bit-subreg-alu.ll b/llvm/test/CodeGen/BPF/32-bit-subreg-alu.ll index 42888ff58f5e2..abec34990044a 100644 --- a/llvm/test/CodeGen/BPF/32-bit-subreg-alu.ll +++ b/llvm/test/CodeGen/BPF/32-bit-subreg-alu.ll @@ -200,7 +200,7 @@ entry: define dso_local i32 @div_i(i32 %a) local_unnamed_addr #0 { entry: %div = udiv i32 %a, 15 -; CHECK: w{{[0-9]+}} /= 15 +; CHECK-NOT: w{{[0-9]+}} /= 15 ret i32 %div } @@ -216,7 +216,7 @@ entry: define dso_local i32 @rem_i(i32 %a) local_unnamed_addr #0 { entry: %rem = urem i32 %a, 15 -; CHECK: w{{[0-9]+}} %= 15 +; CHECK-NOT: w{{[0-9]+}} %= 15 ret i32 %rem } diff --git a/llvm/test/CodeGen/BPF/sdiv_error.ll b/llvm/test/CodeGen/BPF/sdiv_error.ll index a5dcc6271224b..05394f3e05de8 100644 --- a/llvm/test/CodeGen/BPF/sdiv_error.ll +++ b/llvm/test/CodeGen/BPF/sdiv_error.ll @@ -2,7 +2,7 @@ ; RUN: FileCheck %s < %t1 ; CHECK: unsupported signed division -define i32 @test(i32 %len) { - %1 = sdiv i32 %len, 15 - ret i32 %1 +define i64 @test(i64 %len) { + %1 = sdiv i64 %len, 15 + ret i64 %1 } diff --git a/llvm/test/CodeGen/BPF/sdiv_to_mul.ll b/llvm/test/CodeGen/BPF/sdiv_to_mul.ll new file mode 100644 index 0000000000000..7bb1b7badac1f --- /dev/null +++ b/llvm/test/CodeGen/BPF/sdiv_to_mul.ll @@ -0,0 +1,57 @@ +; RUN: llc -march=bpfel -mcpu=v1 < %s | FileCheck --check-prefix=CHECK-V1 %s +; RUN: llc -march=bpfel -mcpu=v4 < %s | FileCheck --check-prefix=CHECK-V4 %s + +target triple = "bpf" + +; struct S { +; int var[3]; +; }; +; int foo1 (struct S *a, struct S *b) +; { +; return a - b; +; } +define dso_local i32 @foo1(ptr noundef %a, ptr noundef %b) local_unnamed_addr { +entry: + %sub.ptr.lhs.cast = ptrtoint ptr %a to i64 + %sub.ptr.rhs.cast = ptrtoint ptr %b to i64 + %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast + %sub.ptr.div = sdiv exact i64 %sub.ptr.sub, 12 + %conv = trunc i64 %sub.ptr.div to i32 + ret i32 %conv +} +; CHECK-V1: r0 = r1 +; CHECK-V1: r0 -= r2 +; CHECK-V1: r0 s>>= 2 +; CHECK-V1: r1 = -6148914691236517205 ll +; CHECK-V1: r0 *= r1 +; CHECK-V1: exit + +; CHECK-V4: r0 = r1 +; CHECK-V4: r0 -= r2 +; CHECK-V4: r0 >>= 2 +; CHECK-V4: w0 *= -1431655765 +; CHECK-V4: exit + +define dso_local noundef range(i32 -143165576, 143165577) i32 @foo2(i32 noundef %a) local_unnamed_addr { +entry: + %div = sdiv i32 %a, 15 + ret i32 %div +} +; CHECK-V1-NOT: r[[#]] s/= 15 +; CHECK-V4-NOT: w[[#]] s/= 15 + +define dso_local noundef range(i32 -14, 15) i32 @foo3(i32 noundef %a) local_unnamed_addr { +entry: + %rem = srem i32 %a, 15 + ret i32 %rem +} +; CHECK-V1-NOT: r[[#]] s%= 15 +; CHECK-V4-NOT: w[[#]] s%= 15 + +define dso_local i64 @foo4(i64 noundef %a) local_unnamed_addr { +entry: + %div = udiv exact i64 %a, 15 + ret i64 %div +} +; CHECK-V1-NOT: r[[#]] /= 15 +; CHECK-V4-NOT: w[[#]] /= 15 diff --git a/llvm/test/CodeGen/BPF/srem_error.ll b/llvm/test/CodeGen/BPF/srem_error.ll index 883e72d32dc7e..8245a47b1ddd2 100644 --- a/llvm/test/CodeGen/BPF/srem_error.ll +++ b/llvm/test/CodeGen/BPF/srem_error.ll @@ -2,7 +2,7 @@ ; RUN: FileCheck %s < %t1 ; CHECK: unsupported signed division -define i32 @test(i32 %len) { - %1 = srem i32 %len, 15 - ret i32 %1 +define i64 @test(i64 %len) { + %1 = srem i64 %len, 15 + ret i64 %1 }