quinnp created this revision.
Herald added subscribers: shchenz, kbarton, nemanjai.
Herald added a project: All.
quinnp requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
This patch refactors `EmitPPCBuiltinExpr` in `CGBuiltin.cpp` to remove
the loop at the begining of the function that emits the arguments and
to delay emitting the arguments until inside the switch statement. This
refactor will put `EmitPPCBuiltinExpr` in line with the strategy of the
target independent function `EmitBuiltinExpr`. Also, this refactor
ensures that arguments are only emitted once.
Tests that included builtins affected by the refactor have been modified
to match expected behaviour.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D121637
Files:
clang/lib/CodeGen/CGBuiltin.cpp
clang/test/CodeGen/PowerPC/builtins-ppc-fastmath.c
clang/test/CodeGen/PowerPC/builtins-ppc-int128.c
clang/test/CodeGen/PowerPC/builtins-ppc-vsx.c
clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-cas.c
clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-fetch.c
clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-fp.c
clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c
clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-sync.c
Index: clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-sync.c
===================================================================
--- clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-sync.c
+++ clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-sync.c
@@ -14,13 +14,11 @@
// CHECK-LABEL: @test_popcntb(
// CHECK: [[TMP0:%.*]] = load i64, i64* @a, align 8
-// CHECK-NEXT: [[TMP1:%.*]] = load i64, i64* @a, align 8
// CHECK-NEXT: [[POPCNTB:%.*]] = call i64 @llvm.ppc.popcntb.i64.i64(i64 [[TMP0]])
// CHECK-NEXT: ret i64 [[POPCNTB]]
//
// CHECK-32-LABEL: @test_popcntb(
// CHECK-32: [[TMP0:%.*]] = load i32, i32* @a, align 4
-// CHECK-32-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
// CHECK-32-NEXT: [[POPCNTB:%.*]] = call i32 @llvm.ppc.popcntb.i32.i32(i32 [[TMP0]])
// CHECK-32-NEXT: ret i32 [[POPCNTB]]
//
@@ -198,13 +196,11 @@
// CHECK-LABEL: @test_builtin_ppc_popcntb(
// CHECK: [[TMP0:%.*]] = load i64, i64* @a, align 8
-// CHECK-NEXT: [[TMP1:%.*]] = load i64, i64* @a, align 8
// CHECK-NEXT: [[POPCNTB:%.*]] = call i64 @llvm.ppc.popcntb.i64.i64(i64 [[TMP0]])
// CHECK-NEXT: ret i64 [[POPCNTB]]
//
// CHECK-32-LABEL: @test_builtin_ppc_popcntb(
// CHECK-32: [[TMP0:%.*]] = load i32, i32* @a, align 4
-// CHECK-32-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
// CHECK-32-NEXT: [[POPCNTB:%.*]] = call i32 @llvm.ppc.popcntb.i32.i32(i32 [[TMP0]])
// CHECK-32-NEXT: ret i32 [[POPCNTB]]
//
Index: clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c
===================================================================
--- clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c
+++ clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c
@@ -15,11 +15,11 @@
// CHECK-LABEL: test_builtin_ppc_rldimi
// CHECK: %res = alloca i64, align 8
// CHECK-NEXT: [[RA:%[0-9]+]] = load i64, i64* @ull, align 8
- // CHECK-NEXT: [[RB:%[0-9]+]] = load i64, i64* @ull, align 8
- // CHECK-NEXT: [[RC:%[0-9]+]] = call i64 @llvm.fshl.i64(i64 [[RA]], i64 [[RA]], i64 63)
- // CHECK-NEXT: [[RD:%[0-9]+]] = and i64 [[RC]], 72057593769492480
- // CHECK-NEXT: [[RE:%[0-9]+]] = and i64 [[RB]], -72057593769492481
- // CHECK-NEXT: [[RF:%[0-9]+]] = or i64 [[RD]], [[RE]]
+ // CHECK-NEXT: [[RB:%[0-9]+]] = call i64 @llvm.fshl.i64(i64 [[RA]], i64 [[RA]], i64 63)
+ // CHECK-NEXT: [[RC:%[0-9]+]] = and i64 [[RB]], 72057593769492480
+ // CHECK-NEXT: [[RD:%[0-9]+]] = load i64, i64* @ull, align 8
+ // CHECK-NEXT: [[RE:%[0-9]+]] = and i64 [[RD]], -72057593769492481
+ // CHECK-NEXT: [[RF:%[0-9]+]] = or i64 [[RC]], [[RE]]
// CHECK-NEXT: store i64 [[RF]], i64* %res, align 8
// CHECK-NEXT: ret void
@@ -31,11 +31,11 @@
// CHECK-LABEL: test_builtin_ppc_rlwimi
// CHECK: %res = alloca i32, align 4
// CHECK-NEXT: [[RA:%[0-9]+]] = load i32, i32* @ui, align 4
- // CHECK-NEXT: [[RB:%[0-9]+]] = load i32, i32* @ui, align 4
- // CHECK-NEXT: [[RC:%[0-9]+]] = call i32 @llvm.fshl.i32(i32 [[RA]], i32 [[RA]], i32 31)
- // CHECK-NEXT: [[RD:%[0-9]+]] = and i32 [[RC]], 16776960
- // CHECK-NEXT: [[RE:%[0-9]+]] = and i32 [[RB]], -16776961
- // CHECK-NEXT: [[RF:%[0-9]+]] = or i32 [[RD]], [[RE]]
+ // CHECK-NEXT: [[RB:%[0-9]+]] = call i32 @llvm.fshl.i32(i32 [[RA]], i32 [[RA]], i32 31)
+ // CHECK-NEXT: [[RC:%[0-9]+]] = and i32 [[RB]], 16776960
+ // CHECK-NEXT: [[RD:%[0-9]+]] = load i32, i32* @ui, align 4
+ // CHECK-NEXT: [[RE:%[0-9]+]] = and i32 [[RD]], -16776961
+ // CHECK-NEXT: [[RF:%[0-9]+]] = or i32 [[RC]], [[RE]]
// CHECK-NEXT: store i32 [[RF]], i32* %res, align 4
// CHECK-NEXT: ret void
Index: clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-fp.c
===================================================================
--- clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-fp.c
+++ clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-fp.c
@@ -15,9 +15,8 @@
// CHECK-LABEL: @test_fric(
// CHECK: [[TMP0:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP1:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.rint.f64(double [[TMP1]])
-// CHECK-NEXT: ret double [[TMP2]]
+// CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.rint.f64(double [[TMP0]])
+// CHECK-NEXT: ret double [[TMP1]]
//
double test_fric() {
return __fric(a);
@@ -25,9 +24,8 @@
// CHECK-LABEL: @test_frim(
// CHECK: [[TMP0:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP1:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.floor.f64(double [[TMP1]])
-// CHECK-NEXT: ret double [[TMP2]]
+// CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.floor.f64(double [[TMP0]])
+// CHECK-NEXT: ret double [[TMP1]]
//
double test_frim() {
return __frim(a);
@@ -35,9 +33,8 @@
// CHECK-LABEL: @test_frims(
// CHECK: [[TMP0:%.*]] = load float, float* @d, align 4
-// CHECK-NEXT: [[TMP1:%.*]] = load float, float* @d, align 4
-// CHECK-NEXT: [[TMP2:%.*]] = call float @llvm.floor.f32(float [[TMP1]])
-// CHECK-NEXT: ret float [[TMP2]]
+// CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.floor.f32(float [[TMP0]])
+// CHECK-NEXT: ret float [[TMP1]]
//
float test_frims() {
return __frims(d);
@@ -45,9 +42,8 @@
// CHECK-LABEL: @test_frin(
// CHECK: [[TMP0:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP1:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.round.f64(double [[TMP1]])
-// CHECK-NEXT: ret double [[TMP2]]
+// CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.round.f64(double [[TMP0]])
+// CHECK-NEXT: ret double [[TMP1]]
//
double test_frin() {
return __frin(a);
@@ -55,9 +51,8 @@
// CHECK-LABEL: @test_frins(
// CHECK: [[TMP0:%.*]] = load float, float* @d, align 4
-// CHECK-NEXT: [[TMP1:%.*]] = load float, float* @d, align 4
-// CHECK-NEXT: [[TMP2:%.*]] = call float @llvm.round.f32(float [[TMP1]])
-// CHECK-NEXT: ret float [[TMP2]]
+// CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.round.f32(float [[TMP0]])
+// CHECK-NEXT: ret float [[TMP1]]
//
float test_frins() {
return __frins(d);
@@ -65,9 +60,8 @@
// CHECK-LABEL: @test_frip(
// CHECK: [[TMP0:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP1:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.ceil.f64(double [[TMP1]])
-// CHECK-NEXT: ret double [[TMP2]]
+// CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.ceil.f64(double [[TMP0]])
+// CHECK-NEXT: ret double [[TMP1]]
//
double test_frip() {
return __frip(a);
@@ -75,9 +69,8 @@
// CHECK-LABEL: @test_frips(
// CHECK: [[TMP0:%.*]] = load float, float* @d, align 4
-// CHECK-NEXT: [[TMP1:%.*]] = load float, float* @d, align 4
-// CHECK-NEXT: [[TMP2:%.*]] = call float @llvm.ceil.f32(float [[TMP1]])
-// CHECK-NEXT: ret float [[TMP2]]
+// CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.ceil.f32(float [[TMP0]])
+// CHECK-NEXT: ret float [[TMP1]]
//
float test_frips() {
return __frips(d);
@@ -85,9 +78,8 @@
// CHECK-LABEL: @test_friz(
// CHECK: [[TMP0:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP1:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.trunc.f64(double [[TMP1]])
-// CHECK-NEXT: ret double [[TMP2]]
+// CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.trunc.f64(double [[TMP0]])
+// CHECK-NEXT: ret double [[TMP1]]
//
double test_friz() {
return __friz(a);
@@ -95,9 +87,8 @@
// CHECK-LABEL: @test_frizs(
// CHECK: [[TMP0:%.*]] = load float, float* @d, align 4
-// CHECK-NEXT: [[TMP1:%.*]] = load float, float* @d, align 4
-// CHECK-NEXT: [[TMP2:%.*]] = call float @llvm.trunc.f32(float [[TMP1]])
-// CHECK-NEXT: ret float [[TMP2]]
+// CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.trunc.f32(float [[TMP0]])
+// CHECK-NEXT: ret float [[TMP1]]
//
float test_frizs() {
return __frizs(d);
@@ -145,9 +136,8 @@
// CHECK-LABEL: @test_fsqrt(
// CHECK: [[TMP0:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP1:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.sqrt.f64(double [[TMP1]])
-// CHECK-NEXT: ret double [[TMP2]]
+// CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.sqrt.f64(double [[TMP0]])
+// CHECK-NEXT: ret double [[TMP1]]
//
double test_fsqrt() {
return __fsqrt(a);
@@ -155,9 +145,8 @@
// CHECK-LABEL: @test_fsqrts(
// CHECK: [[TMP0:%.*]] = load float, float* @d, align 4
-// CHECK-NEXT: [[TMP1:%.*]] = load float, float* @d, align 4
-// CHECK-NEXT: [[TMP2:%.*]] = call float @llvm.sqrt.f32(float [[TMP1]])
-// CHECK-NEXT: ret float [[TMP2]]
+// CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.sqrt.f32(float [[TMP0]])
+// CHECK-NEXT: ret float [[TMP1]]
//
float test_fsqrts() {
return __fsqrts(d);
@@ -165,9 +154,8 @@
// CHECK-LABEL: @test_builtin_ppc_fric(
// CHECK: [[TMP0:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP1:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.rint.f64(double [[TMP1]])
-// CHECK-NEXT: ret double [[TMP2]]
+// CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.rint.f64(double [[TMP0]])
+// CHECK-NEXT: ret double [[TMP1]]
//
double test_builtin_ppc_fric() {
return __builtin_ppc_fric(a);
@@ -175,9 +163,8 @@
// CHECK-LABEL: @test_builtin_ppc_frim(
// CHECK: [[TMP0:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP1:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.floor.f64(double [[TMP1]])
-// CHECK-NEXT: ret double [[TMP2]]
+// CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.floor.f64(double [[TMP0]])
+// CHECK-NEXT: ret double [[TMP1]]
//
double test_builtin_ppc_frim() {
return __builtin_ppc_frim(a);
@@ -185,9 +172,8 @@
// CHECK-LABEL: @test_builtin_ppc_frims(
// CHECK: [[TMP0:%.*]] = load float, float* @d, align 4
-// CHECK-NEXT: [[TMP1:%.*]] = load float, float* @d, align 4
-// CHECK-NEXT: [[TMP2:%.*]] = call float @llvm.floor.f32(float [[TMP1]])
-// CHECK-NEXT: ret float [[TMP2]]
+// CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.floor.f32(float [[TMP0]])
+// CHECK-NEXT: ret float [[TMP1]]
//
float test_builtin_ppc_frims() {
return __builtin_ppc_frims(d);
@@ -195,9 +181,8 @@
// CHECK-LABEL: @test_builtin_ppc_frin(
// CHECK: [[TMP0:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP1:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.round.f64(double [[TMP1]])
-// CHECK-NEXT: ret double [[TMP2]]
+// CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.round.f64(double [[TMP0]])
+// CHECK-NEXT: ret double [[TMP1]]
//
double test_builtin_ppc_frin() {
return __builtin_ppc_frin(a);
@@ -205,9 +190,8 @@
// CHECK-LABEL: @test_builtin_ppc_frins(
// CHECK: [[TMP0:%.*]] = load float, float* @d, align 4
-// CHECK-NEXT: [[TMP1:%.*]] = load float, float* @d, align 4
-// CHECK-NEXT: [[TMP2:%.*]] = call float @llvm.round.f32(float [[TMP1]])
-// CHECK-NEXT: ret float [[TMP2]]
+// CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.round.f32(float [[TMP0]])
+// CHECK-NEXT: ret float [[TMP1]]
//
float test_builtin_ppc_frins() {
return __builtin_ppc_frins(d);
@@ -215,9 +199,8 @@
// CHECK-LABEL: @test_builtin_ppc_frip(
// CHECK: [[TMP0:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP1:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.ceil.f64(double [[TMP1]])
-// CHECK-NEXT: ret double [[TMP2]]
+// CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.ceil.f64(double [[TMP0]])
+// CHECK-NEXT: ret double [[TMP1]]
//
double test_builtin_ppc_frip() {
return __builtin_ppc_frip(a);
@@ -225,9 +208,8 @@
// CHECK-LABEL: @test_builtin_ppc_frips(
// CHECK: [[TMP0:%.*]] = load float, float* @d, align 4
-// CHECK-NEXT: [[TMP1:%.*]] = load float, float* @d, align 4
-// CHECK-NEXT: [[TMP2:%.*]] = call float @llvm.ceil.f32(float [[TMP1]])
-// CHECK-NEXT: ret float [[TMP2]]
+// CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.ceil.f32(float [[TMP0]])
+// CHECK-NEXT: ret float [[TMP1]]
//
float test_builtin_ppc_frips() {
return __builtin_ppc_frips(d);
@@ -235,9 +217,8 @@
// CHECK-LABEL: @test_builtin_ppc_friz(
// CHECK: [[TMP0:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP1:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.trunc.f64(double [[TMP1]])
-// CHECK-NEXT: ret double [[TMP2]]
+// CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.trunc.f64(double [[TMP0]])
+// CHECK-NEXT: ret double [[TMP1]]
//
double test_builtin_ppc_friz() {
return __builtin_ppc_friz(a);
@@ -245,9 +226,8 @@
// CHECK-LABEL: @test_builtin_ppc_frizs(
// CHECK: [[TMP0:%.*]] = load float, float* @d, align 4
-// CHECK-NEXT: [[TMP1:%.*]] = load float, float* @d, align 4
-// CHECK-NEXT: [[TMP2:%.*]] = call float @llvm.trunc.f32(float [[TMP1]])
-// CHECK-NEXT: ret float [[TMP2]]
+// CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.trunc.f32(float [[TMP0]])
+// CHECK-NEXT: ret float [[TMP1]]
//
float test_builtin_ppc_frizs() {
return __builtin_ppc_frizs(d);
@@ -295,9 +275,8 @@
// CHECK-LABEL: @test_builtin_ppc_fsqrt(
// CHECK: [[TMP0:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP1:%.*]] = load double, double* @a, align 8
-// CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.sqrt.f64(double [[TMP1]])
-// CHECK-NEXT: ret double [[TMP2]]
+// CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.sqrt.f64(double [[TMP0]])
+// CHECK-NEXT: ret double [[TMP1]]
//
double test_builtin_ppc_fsqrt() {
return __builtin_ppc_fsqrt(a);
@@ -305,9 +284,8 @@
// CHECK-LABEL: @test_builtin_ppc_fsqrts(
// CHECK: [[TMP0:%.*]] = load float, float* @d, align 4
-// CHECK-NEXT: [[TMP1:%.*]] = load float, float* @d, align 4
-// CHECK-NEXT: [[TMP2:%.*]] = call float @llvm.sqrt.f32(float [[TMP1]])
-// CHECK-NEXT: ret float [[TMP2]]
+// CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.sqrt.f32(float [[TMP0]])
+// CHECK-NEXT: ret float [[TMP1]]
//
float test_builtin_ppc_fsqrts() {
return __builtin_ppc_fsqrts(d);
Index: clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-fetch.c
===================================================================
--- clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-fetch.c
+++ clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-fetch.c
@@ -12,8 +12,7 @@
// CHECK-NEXT: store i32 [[A:%.*]], i32* [[A_ADDR]], align 4
// CHECK-NEXT: store i32 [[B:%.*]], i32* [[B_ADDR]], align 4
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[B_ADDR]], align 4
-// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[B_ADDR]], align 4
-// CHECK-NEXT: [[TMP2:%.*]] = atomicrmw add i32* [[A_ADDR]], i32 [[TMP1]] monotonic, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = atomicrmw add i32* [[A_ADDR]], i32 [[TMP0]] monotonic, align 4
// CHECK-NEXT: ret void
//
void test_builtin_ppc_fetch_and_add(int a, int b) {
@@ -27,8 +26,7 @@
// CHECK-NEXT: store i64 [[A:%.*]], i64* [[A_ADDR]], align 8
// CHECK-NEXT: store i64 [[B:%.*]], i64* [[B_ADDR]], align 8
// CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[B_ADDR]], align 8
-// CHECK-NEXT: [[TMP1:%.*]] = load i64, i64* [[B_ADDR]], align 8
-// CHECK-NEXT: [[TMP2:%.*]] = atomicrmw add i64* [[A_ADDR]], i64 [[TMP1]] monotonic, align 8
+// CHECK-NEXT: [[TMP1:%.*]] = atomicrmw add i64* [[A_ADDR]], i64 [[TMP0]] monotonic, align 8
// CHECK-NEXT: ret void
//
void test_builtin_ppc_fetch_and_addlp(long a, long b) {
@@ -41,8 +39,7 @@
// CHECK-NEXT: store i32 [[A:%.*]], i32* [[A_ADDR]], align 4
// CHECK-NEXT: store i32 [[B:%.*]], i32* [[B_ADDR]], align 4
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[B_ADDR]], align 4
-// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[B_ADDR]], align 4
-// CHECK-NEXT: [[TMP2:%.*]] = atomicrmw and i32* [[A_ADDR]], i32 [[TMP1]] monotonic, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = atomicrmw and i32* [[A_ADDR]], i32 [[TMP0]] monotonic, align 4
// CHECK-NEXT: ret void
//
void test_builtin_ppc_fetch_and_and(unsigned int a, unsigned int b) {
@@ -55,8 +52,7 @@
// CHECK-NEXT: store i64 [[A:%.*]], i64* [[A_ADDR]], align 8
// CHECK-NEXT: store i64 [[B:%.*]], i64* [[B_ADDR]], align 8
// CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[B_ADDR]], align 8
-// CHECK-NEXT: [[TMP1:%.*]] = load i64, i64* [[B_ADDR]], align 8
-// CHECK-NEXT: [[TMP2:%.*]] = atomicrmw and i64* [[A_ADDR]], i64 [[TMP1]] monotonic, align 8
+// CHECK-NEXT: [[TMP1:%.*]] = atomicrmw and i64* [[A_ADDR]], i64 [[TMP0]] monotonic, align 8
// CHECK-NEXT: ret void
//
void test_builtin_ppc_fetch_and_andlp(unsigned long a, unsigned long b) {
@@ -69,8 +65,7 @@
// CHECK-NEXT: store i32 [[A:%.*]], i32* [[A_ADDR]], align 4
// CHECK-NEXT: store i32 [[B:%.*]], i32* [[B_ADDR]], align 4
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[B_ADDR]], align 4
-// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[B_ADDR]], align 4
-// CHECK-NEXT: [[TMP2:%.*]] = atomicrmw or i32* [[A_ADDR]], i32 [[TMP1]] monotonic, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = atomicrmw or i32* [[A_ADDR]], i32 [[TMP0]] monotonic, align 4
// CHECK-NEXT: ret void
//
void test_builtin_ppc_fetch_and_or(unsigned int a, unsigned int b) {
@@ -83,8 +78,7 @@
// CHECK-NEXT: store i64 [[A:%.*]], i64* [[A_ADDR]], align 8
// CHECK-NEXT: store i64 [[B:%.*]], i64* [[B_ADDR]], align 8
// CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[B_ADDR]], align 8
-// CHECK-NEXT: [[TMP1:%.*]] = load i64, i64* [[B_ADDR]], align 8
-// CHECK-NEXT: [[TMP2:%.*]] = atomicrmw or i64* [[A_ADDR]], i64 [[TMP1]] monotonic, align 8
+// CHECK-NEXT: [[TMP1:%.*]] = atomicrmw or i64* [[A_ADDR]], i64 [[TMP0]] monotonic, align 8
// CHECK-NEXT: ret void
//
void test_builtin_ppc_fetch_and_orlp(unsigned long a, unsigned long b) {
@@ -97,8 +91,7 @@
// CHECK-NEXT: store i32 [[A:%.*]], i32* [[A_ADDR]], align 4
// CHECK-NEXT: store i32 [[B:%.*]], i32* [[B_ADDR]], align 4
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[B_ADDR]], align 4
-// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[B_ADDR]], align 4
-// CHECK-NEXT: [[TMP2:%.*]] = atomicrmw xchg i32* [[A_ADDR]], i32 [[TMP1]] monotonic, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = atomicrmw xchg i32* [[A_ADDR]], i32 [[TMP0]] monotonic, align 4
// CHECK-NEXT: ret void
//
void test_builtin_ppc_fetch_and_swap(unsigned int a, unsigned int b) {
@@ -111,8 +104,7 @@
// CHECK-NEXT: store i64 [[A:%.*]], i64* [[A_ADDR]], align 8
// CHECK-NEXT: store i64 [[B:%.*]], i64* [[B_ADDR]], align 8
// CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[B_ADDR]], align 8
-// CHECK-NEXT: [[TMP1:%.*]] = load i64, i64* [[B_ADDR]], align 8
-// CHECK-NEXT: [[TMP2:%.*]] = atomicrmw xchg i64* [[A_ADDR]], i64 [[TMP1]] monotonic, align 8
+// CHECK-NEXT: [[TMP1:%.*]] = atomicrmw xchg i64* [[A_ADDR]], i64 [[TMP0]] monotonic, align 8
// CHECK-NEXT: ret void
//
void test_builtin_ppc_fetch_and_swaplp(unsigned long a, unsigned long b) {
Index: clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-cas.c
===================================================================
--- clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-cas.c
+++ clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-cas.c
@@ -14,9 +14,9 @@
// CHECK-NEXT: store i32 [[A:%.*]], i32* [[A_ADDR]], align 4
// CHECK-NEXT: store i32 [[B:%.*]], i32* [[B_ADDR]], align 4
// CHECK-NEXT: store i32 [[C:%.*]], i32* [[C_ADDR]], align 4
-// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[C_ADDR]], align 4
-// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[B_ADDR]], align 4
-// CHECK-NEXT: [[TMP2:%.*]] = cmpxchg weak volatile i32* [[A_ADDR]], i32 [[TMP1]], i32 [[TMP0]] monotonic monotonic, align 4
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[C_ADDR]], align 4
+// CHECK-NEXT: [[TMP2:%.*]] = cmpxchg weak volatile i32* [[A_ADDR]], i32 [[TMP0]], i32 [[TMP1]] monotonic monotonic, align 4
// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0
// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
// CHECK-NEXT: store i32 [[TMP3]], i32* [[B_ADDR]], align 4
@@ -36,9 +36,9 @@
// CHECK-NEXT: store i64 [[A:%.*]], i64* [[A_ADDR]], align 8
// CHECK-NEXT: store i64 [[B:%.*]], i64* [[B_ADDR]], align 8
// CHECK-NEXT: store i64 [[C:%.*]], i64* [[C_ADDR]], align 8
-// CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[C_ADDR]], align 8
-// CHECK-NEXT: [[TMP1:%.*]] = load i64, i64* [[B_ADDR]], align 8
-// CHECK-NEXT: [[TMP2:%.*]] = cmpxchg weak volatile i64* [[A_ADDR]], i64 [[TMP1]], i64 [[TMP0]] monotonic monotonic, align 8
+// CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[B_ADDR]], align 8
+// CHECK-NEXT: [[TMP1:%.*]] = load i64, i64* [[C_ADDR]], align 8
+// CHECK-NEXT: [[TMP2:%.*]] = cmpxchg weak volatile i64* [[A_ADDR]], i64 [[TMP0]], i64 [[TMP1]] monotonic monotonic, align 8
// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i64, i1 } [[TMP2]], 0
// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i64, i1 } [[TMP2]], 1
// CHECK-NEXT: store i64 [[TMP3]], i64* [[B_ADDR]], align 8
Index: clang/test/CodeGen/PowerPC/builtins-ppc-vsx.c
===================================================================
--- clang/test/CodeGen/PowerPC/builtins-ppc-vsx.c
+++ clang/test/CodeGen/PowerPC/builtins-ppc-vsx.c
@@ -2213,8 +2213,6 @@
void test_vector_cpsgn_float(vector float a, vector float b) {
// CHECK-LABEL: test_vector_cpsgn_float
-// CHECK-DAG: load{{.*}}%__a
-// CHECK-DAG: load{{.*}}%__b
// CHECK-NOT: SEPARATOR
// CHECK-DAG: [[RA:%[0-9]+]] = load <4 x float>, <4 x float>* %__a.addr
// CHECK-DAG: [[RB:%[0-9]+]] = load <4 x float>, <4 x float>* %__b.addr
@@ -2224,8 +2222,6 @@
void test_vector_cpsgn_double(vector double a, vector double b) {
// CHECK-LABEL: test_vector_cpsgn_double
-// CHECK-DAG: load{{.*}}%__a
-// CHECK-DAG: load{{.*}}%__b
// CHECK-NOT: SEPARATOR
// CHECK-DAG: [[RA:%[0-9]+]] = load <2 x double>, <2 x double>* %__a.addr
// CHECK-DAG: [[RB:%[0-9]+]] = load <2 x double>, <2 x double>* %__b.addr
@@ -2235,8 +2231,6 @@
void test_builtin_xvcpsgnsp(vector float a, vector float b) {
// CHECK-LABEL: test_builtin_xvcpsgnsp
-// CHECK-DAG: load{{.*}}%a
-// CHECK-DAG: load{{.*}}%b
// CHECK-NOT: SEPARATOR
// CHECK-DAG: [[RA:%[0-9]+]] = load <4 x float>, <4 x float>* %a.addr
// CHECK-DAG: [[RB:%[0-9]+]] = load <4 x float>, <4 x float>* %b.addr
@@ -2246,8 +2240,6 @@
void test_builtin_xvcpsgndp(vector double a, vector double b) {
// CHECK-LABEL: test_builtin_xvcpsgndp
-// CHECK-DAG: load{{.*}}%a
-// CHECK-DAG: load{{.*}}%b
// CHECK-NOT: SEPARATOR
// CHECK-DAG: [[RA:%[0-9]+]] = load <2 x double>, <2 x double>* %a.addr
// CHECK-DAG: [[RB:%[0-9]+]] = load <2 x double>, <2 x double>* %b.addr
Index: clang/test/CodeGen/PowerPC/builtins-ppc-int128.c
===================================================================
--- clang/test/CodeGen/PowerPC/builtins-ppc-int128.c
+++ clang/test/CodeGen/PowerPC/builtins-ppc-int128.c
@@ -16,7 +16,8 @@
// CHECK-LABEL-LE: testVectorInt128Pack
res_vslll = __builtin_pack_vector_int128(aull[0], aull[1]);
// CHECK: %[[V1:[0-9]+]] = insertelement <2 x i64> undef, i64 %{{[0-9]+}}, i64 0
-// CHECK-NEXT: %[[V2:[0-9]+]] = insertelement <2 x i64> %[[V1]], i64 %{{[0-9]+}}, i64 1
+// CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* getelementptr inbounds ([2 x i64], [2 x i64]* @aull, i64 0, i64 1), align 8
+// CHECK-NEXT: %[[V2:[0-9]+]] = insertelement <2 x i64> %[[V1]], i64 [[TMP0]], i64 1
// CHECK-NEXT: bitcast <2 x i64> %[[V2]] to <1 x i128>
// CHECK-LE: %[[V1:[0-9]+]] = insertelement <2 x i64> undef, i64 %{{[0-9]+}}, i64 1
Index: clang/test/CodeGen/PowerPC/builtins-ppc-fastmath.c
===================================================================
--- clang/test/CodeGen/PowerPC/builtins-ppc-fastmath.c
+++ clang/test/CodeGen/PowerPC/builtins-ppc-fastmath.c
@@ -18,11 +18,9 @@
// CHECK-LABEL: @test_flags_recipdivf(
// CHECK: [[TMP0:%.*]] = load <4 x float>, <4 x float>* @a, align 16
// CHECK-NEXT: [[TMP1:%.*]] = load <4 x float>, <4 x float>* @b, align 16
-// CHECK-NEXT: [[TMP2:%.*]] = load <4 x float>, <4 x float>* @a, align 16
-// CHECK-NEXT: [[TMP3:%.*]] = load <4 x float>, <4 x float>* @b, align 16
-// CHECK-NEXT: [[RECIPDIV:%.*]] = fdiv fast <4 x float> [[TMP2]], [[TMP3]]
-// CHECK-NEXT: [[TMP4:%.*]] = load <4 x float>, <4 x float>* @c, align 16
-// CHECK-NEXT: [[ADD:%.*]] = fadd <4 x float> [[RECIPDIV]], [[TMP4]]
+// CHECK-NEXT: [[RECIPDIV:%.*]] = fdiv fast <4 x float> [[TMP0]], [[TMP1]]
+// CHECK-NEXT: [[TMP2:%.*]] = load <4 x float>, <4 x float>* @c, align 16
+// CHECK-NEXT: [[ADD:%.*]] = fadd <4 x float> [[RECIPDIV]], [[TMP2]]
// CHECK-NEXT: ret <4 x float> [[ADD]]
//
vector float test_flags_recipdivf() {
@@ -32,11 +30,9 @@
// CHECK-LABEL: @test_flags_recipdivd(
// CHECK: [[TMP0:%.*]] = load <2 x double>, <2 x double>* @d, align 16
// CHECK-NEXT: [[TMP1:%.*]] = load <2 x double>, <2 x double>* @e, align 16
-// CHECK-NEXT: [[TMP2:%.*]] = load <2 x double>, <2 x double>* @d, align 16
-// CHECK-NEXT: [[TMP3:%.*]] = load <2 x double>, <2 x double>* @e, align 16
-// CHECK-NEXT: [[RECIPDIV:%.*]] = fdiv fast <2 x double> [[TMP2]], [[TMP3]]
-// CHECK-NEXT: [[TMP4:%.*]] = load <2 x double>, <2 x double>* @f, align 16
-// CHECK-NEXT: [[ADD:%.*]] = fadd <2 x double> [[RECIPDIV]], [[TMP4]]
+// CHECK-NEXT: [[RECIPDIV:%.*]] = fdiv fast <2 x double> [[TMP0]], [[TMP1]]
+// CHECK-NEXT: [[TMP2:%.*]] = load <2 x double>, <2 x double>* @f, align 16
+// CHECK-NEXT: [[ADD:%.*]] = fadd <2 x double> [[RECIPDIV]], [[TMP2]]
// CHECK-NEXT: ret <2 x double> [[ADD]]
//
vector double test_flags_recipdivd() {
@@ -45,11 +41,10 @@
// CHECK-LABEL: @test_flags_rsqrtf(
// CHECK: [[TMP0:%.*]] = load <4 x float>, <4 x float>* @a, align 16
-// CHECK-NEXT: [[TMP1:%.*]] = load <4 x float>, <4 x float>* @a, align 16
-// CHECK-NEXT: [[TMP2:%.*]] = call fast <4 x float> @llvm.sqrt.v4f32(<4 x float> [[TMP1]])
-// CHECK-NEXT: [[RSQRT:%.*]] = fdiv fast <4 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>, [[TMP2]]
-// CHECK-NEXT: [[TMP3:%.*]] = load <4 x float>, <4 x float>* @b, align 16
-// CHECK-NEXT: [[ADD:%.*]] = fadd <4 x float> [[RSQRT]], [[TMP3]]
+// CHECK-NEXT: [[TMP1:%.*]] = call fast <4 x float> @llvm.sqrt.v4f32(<4 x float> [[TMP0]])
+// CHECK-NEXT: [[RSQRT:%.*]] = fdiv fast <4 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>, [[TMP1]]
+// CHECK-NEXT: [[TMP2:%.*]] = load <4 x float>, <4 x float>* @b, align 16
+// CHECK-NEXT: [[ADD:%.*]] = fadd <4 x float> [[RSQRT]], [[TMP2]]
// CHECK-NEXT: ret <4 x float> [[ADD]]
//
vector float test_flags_rsqrtf() {
@@ -58,11 +53,10 @@
// CHECK-LABEL: @test_flags_rsqrtd(
// CHECK: [[TMP0:%.*]] = load <2 x double>, <2 x double>* @d, align 16
-// CHECK-NEXT: [[TMP1:%.*]] = load <2 x double>, <2 x double>* @d, align 16
-// CHECK-NEXT: [[TMP2:%.*]] = call fast <2 x double> @llvm.sqrt.v2f64(<2 x double> [[TMP1]])
-// CHECK-NEXT: [[RSQRT:%.*]] = fdiv fast <2 x double> <double 1.000000e+00, double 1.000000e+00>, [[TMP2]]
-// CHECK-NEXT: [[TMP3:%.*]] = load <2 x double>, <2 x double>* @e, align 16
-// CHECK-NEXT: [[ADD:%.*]] = fadd <2 x double> [[RSQRT]], [[TMP3]]
+// CHECK-NEXT: [[TMP1:%.*]] = call fast <2 x double> @llvm.sqrt.v2f64(<2 x double> [[TMP0]])
+// CHECK-NEXT: [[RSQRT:%.*]] = fdiv fast <2 x double> <double 1.000000e+00, double 1.000000e+00>, [[TMP1]]
+// CHECK-NEXT: [[TMP2:%.*]] = load <2 x double>, <2 x double>* @e, align 16
+// CHECK-NEXT: [[ADD:%.*]] = fadd <2 x double> [[RSQRT]], [[TMP2]]
// CHECK-NEXT: ret <2 x double> [[ADD]]
//
vector double test_flags_rsqrtd() {
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -15202,14 +15202,6 @@
Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
const CallExpr *E) {
- SmallVector<Value*, 4> Ops;
-
- for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) {
- if (E->getArg(i)->getType()->isArrayType())
- Ops.push_back(EmitArrayToPointerDecay(E->getArg(i)).getPointer());
- else
- Ops.push_back(EmitScalarExpr(E->getArg(i)));
- }
Intrinsic::ID ID = Intrinsic::not_intrinsic;
@@ -15236,6 +15228,9 @@
case PPC::BI__builtin_vsx_lxvl:
case PPC::BI__builtin_vsx_lxvll:
{
+ SmallVector<Value *, 2> Ops;
+ Ops.push_back(EmitScalarExpr(E->getArg(0)));
+ Ops.push_back(EmitScalarExpr(E->getArg(1)));
if(BuiltinID == PPC::BI__builtin_vsx_lxvl ||
BuiltinID == PPC::BI__builtin_vsx_lxvll){
Ops[0] = Builder.CreateBitCast(Ops[0], Int8PtrTy);
@@ -15304,6 +15299,10 @@
case PPC::BI__builtin_vsx_stxvl:
case PPC::BI__builtin_vsx_stxvll:
{
+ SmallVector<Value *, 3> Ops;
+ Ops.push_back(EmitScalarExpr(E->getArg(0)));
+ Ops.push_back(EmitScalarExpr(E->getArg(1)));
+ Ops.push_back(EmitScalarExpr(E->getArg(2)));
if(BuiltinID == PPC::BI__builtin_vsx_stxvl ||
BuiltinID == PPC::BI__builtin_vsx_stxvll ){
Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy);
@@ -15353,16 +15352,18 @@
return Builder.CreateCall(F, Ops, "");
}
case PPC::BI__builtin_vsx_ldrmb: {
+ Value *Op0 = EmitScalarExpr(E->getArg(0));
+ Value *Op1 = EmitScalarExpr(E->getArg(1));
// Essentially boils down to performing an unaligned VMX load sequence so
// as to avoid crossing a page boundary and then shuffling the elements
// into the right side of the vector register.
- int64_t NumBytes = cast<ConstantInt>(Ops[1])->getZExtValue();
+ int64_t NumBytes = cast<ConstantInt>(Op1)->getZExtValue();
llvm::Type *ResTy = ConvertType(E->getType());
bool IsLE = getTarget().isLittleEndian();
// If the user wants the entire vector, just load the entire vector.
if (NumBytes == 16) {
- Value *BC = Builder.CreateBitCast(Ops[0], ResTy->getPointerTo());
+ Value *BC = Builder.CreateBitCast(Op0, ResTy->getPointerTo());
Value *LD =
Builder.CreateLoad(Address(BC, ResTy, CharUnits::fromQuantity(1)));
if (!IsLE)
@@ -15380,16 +15381,14 @@
: Intrinsic::ppc_altivec_lvsl);
llvm::Function *Vperm = CGM.getIntrinsic(Intrinsic::ppc_altivec_vperm);
Value *HiMem = Builder.CreateGEP(
- Int8Ty, Ops[0], ConstantInt::get(Ops[1]->getType(), NumBytes - 1));
- Value *LoLd = Builder.CreateCall(Lvx, Ops[0], "ld.lo");
+ Int8Ty, Op0, ConstantInt::get(Op1->getType(), NumBytes - 1));
+ Value *LoLd = Builder.CreateCall(Lvx, Op0, "ld.lo");
Value *HiLd = Builder.CreateCall(Lvx, HiMem, "ld.hi");
- Value *Mask1 = Builder.CreateCall(Lvs, Ops[0], "mask1");
+ Value *Mask1 = Builder.CreateCall(Lvs, Op0, "mask1");
- Ops.clear();
- Ops.push_back(IsLE ? HiLd : LoLd);
- Ops.push_back(IsLE ? LoLd : HiLd);
- Ops.push_back(Mask1);
- Value *AllElts = Builder.CreateCall(Vperm, Ops, "shuffle1");
+ Op0 = IsLE ? HiLd : LoLd;
+ Op1 = IsLE ? LoLd : HiLd;
+ Value *AllElts = Builder.CreateCall(Vperm, {Op0, Op1, Mask1}, "shuffle1");
Constant *Zero = llvm::Constant::getNullValue(IsLE ? ResTy : AllElts->getType());
if (IsLE) {
@@ -15410,23 +15409,25 @@
Builder.CreateCall(Vperm, {Zero, AllElts, Mask2}, "shuffle2"), ResTy);
}
case PPC::BI__builtin_vsx_strmb: {
- int64_t NumBytes = cast<ConstantInt>(Ops[1])->getZExtValue();
+ Value *Op0 = EmitScalarExpr(E->getArg(0));
+ Value *Op2 = EmitScalarExpr(E->getArg(2));
+ int64_t NumBytes =
+ cast<ConstantInt>(EmitScalarExpr(E->getArg(1)))->getZExtValue();
bool IsLE = getTarget().isLittleEndian();
auto StoreSubVec = [&](unsigned Width, unsigned Offset, unsigned EltNo) {
// Storing the whole vector, simply store it on BE and reverse bytes and
// store on LE.
if (Width == 16) {
- Value *BC =
- Builder.CreateBitCast(Ops[0], Ops[2]->getType()->getPointerTo());
- Value *StVec = Ops[2];
+ Value *BC = Builder.CreateBitCast(Op0, Op2->getType()->getPointerTo());
+ Value *StVec = Op2;
if (IsLE) {
SmallVector<int, 16> RevMask;
for (int Idx = 0; Idx < 16; Idx++)
RevMask.push_back(15 - Idx);
- StVec = Builder.CreateShuffleVector(Ops[2], Ops[2], RevMask);
+ StVec = Builder.CreateShuffleVector(Op2, Op2, RevMask);
}
return Builder.CreateStore(
- StVec, Address(BC, Ops[2]->getType(), CharUnits::fromQuantity(1)));
+ StVec, Address(BC, Op2->getType(), CharUnits::fromQuantity(1)));
}
auto *ConvTy = Int64Ty;
unsigned NumElts = 0;
@@ -15451,9 +15452,9 @@
break;
}
Value *Vec = Builder.CreateBitCast(
- Ops[2], llvm::FixedVectorType::get(ConvTy, NumElts));
- Value *Ptr = Builder.CreateGEP(Int8Ty, Ops[0],
- ConstantInt::get(Int64Ty, Offset));
+ Op2, llvm::FixedVectorType::get(ConvTy, NumElts));
+ Value *Ptr =
+ Builder.CreateGEP(Int8Ty, Op0, ConstantInt::get(Int64Ty, Offset));
Value *PtrBC = Builder.CreateBitCast(Ptr, ConvTy->getPointerTo());
Value *Elt = Builder.CreateExtractElement(Vec, EltNo);
if (IsLE && Width > 1) {
@@ -15527,17 +15528,20 @@
}
case PPC::BI__builtin_altivec_vec_replace_elt:
case PPC::BI__builtin_altivec_vec_replace_unaligned: {
+ Value *Op0 = EmitScalarExpr(E->getArg(0));
+ Value *Op1 = EmitScalarExpr(E->getArg(1));
+ Value *Op2 = EmitScalarExpr(E->getArg(2));
// The third argument of vec_replace_elt and vec_replace_unaligned must
// be a compile time constant and will be emitted either to the vinsw
// or vinsd instruction.
- ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]);
+ ConstantInt *ArgCI = dyn_cast<ConstantInt>(Op2);
assert(ArgCI &&
"Third Arg to vinsw/vinsd intrinsic must be a constant integer!");
llvm::Type *ResultType = ConvertType(E->getType());
llvm::Function *F = nullptr;
Value *Call = nullptr;
int64_t ConstArg = ArgCI->getSExtValue();
- unsigned ArgWidth = Ops[1]->getType()->getPrimitiveSizeInBits();
+ unsigned ArgWidth = Op1->getType()->getPrimitiveSizeInBits();
bool Is32Bit = false;
assert((ArgWidth == 32 || ArgWidth == 64) && "Invalid argument width");
// The input to vec_replace_elt is an element index, not a byte index.
@@ -15559,24 +15563,24 @@
if (getTarget().isLittleEndian())
ConstArg = 8 - ConstArg;
}
- Ops[2] = ConstantInt::getSigned(Int32Ty, ConstArg);
+ Op2 = ConstantInt::getSigned(Int32Ty, ConstArg);
// Depending on ArgWidth, the input vector could be a float or a double.
// If the input vector is a float type, bitcast the inputs to integers. Or,
// if the input vector is a double, bitcast the inputs to 64-bit integers.
- if (!Ops[1]->getType()->isIntegerTy(ArgWidth)) {
- Ops[0] = Builder.CreateBitCast(
- Ops[0], Is32Bit ? llvm::FixedVectorType::get(Int32Ty, 4)
- : llvm::FixedVectorType::get(Int64Ty, 2));
- Ops[1] = Builder.CreateBitCast(Ops[1], Is32Bit ? Int32Ty : Int64Ty);
+ if (!Op1->getType()->isIntegerTy(ArgWidth)) {
+ Op0 = Builder.CreateBitCast(
+ Op0, Is32Bit ? llvm::FixedVectorType::get(Int32Ty, 4)
+ : llvm::FixedVectorType::get(Int64Ty, 2));
+ Op1 = Builder.CreateBitCast(Op1, Is32Bit ? Int32Ty : Int64Ty);
}
// Emit the call to vinsw or vinsd.
- Call = Builder.CreateCall(F, Ops);
+ Call = Builder.CreateCall(F, {Op0, Op1, Op2});
// Depending on the builtin, bitcast to the approriate result type.
if (BuiltinID == PPC::BI__builtin_altivec_vec_replace_elt &&
- !Ops[1]->getType()->isIntegerTy())
+ !Op1->getType()->isIntegerTy())
return Builder.CreateBitCast(Call, ResultType);
else if (BuiltinID == PPC::BI__builtin_altivec_vec_replace_elt &&
- Ops[1]->getType()->isIntegerTy())
+ Op1->getType()->isIntegerTy())
return Call;
else
return Builder.CreateBitCast(Call,
@@ -15593,15 +15597,15 @@
}
case PPC::BI__builtin_altivec_vadduqm:
case PPC::BI__builtin_altivec_vsubuqm: {
+ Value *Op0 = EmitScalarExpr(E->getArg(0));
+ Value *Op1 = EmitScalarExpr(E->getArg(1));
llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128);
- Ops[0] =
- Builder.CreateBitCast(Ops[0], llvm::FixedVectorType::get(Int128Ty, 1));
- Ops[1] =
- Builder.CreateBitCast(Ops[1], llvm::FixedVectorType::get(Int128Ty, 1));
+ Op0 = Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(Int128Ty, 1));
+ Op1 = Builder.CreateBitCast(Op1, llvm::FixedVectorType::get(Int128Ty, 1));
if (BuiltinID == PPC::BI__builtin_altivec_vadduqm)
- return Builder.CreateAdd(Ops[0], Ops[1], "vadduqm");
+ return Builder.CreateAdd(Op0, Op1, "vadduqm");
else
- return Builder.CreateSub(Ops[0], Ops[1], "vsubuqm");
+ return Builder.CreateSub(Op0, Op1, "vsubuqm");
}
// Rotate and insert under mask operation.
// __rldimi(rs, is, shift, mask)
@@ -15610,29 +15614,36 @@
// (rotl(rs, shift) & mask) | (is & ~mask)
case PPC::BI__builtin_ppc_rldimi:
case PPC::BI__builtin_ppc_rlwimi: {
- llvm::Type *Ty = Ops[0]->getType();
+ Value *Op0 = EmitScalarExpr(E->getArg(0));
+ Value *Op2 = EmitScalarExpr(E->getArg(2));
+ Value *Op3 = EmitScalarExpr(E->getArg(3));
+ llvm::Type *Ty = Op0->getType();
Function *F = CGM.getIntrinsic(Intrinsic::fshl, Ty);
if (BuiltinID == PPC::BI__builtin_ppc_rldimi)
- Ops[2] = Builder.CreateZExt(Ops[2], Int64Ty);
- Value *Shift = Builder.CreateCall(F, {Ops[0], Ops[0], Ops[2]});
- Value *X = Builder.CreateAnd(Shift, Ops[3]);
- Value *Y = Builder.CreateAnd(Ops[1], Builder.CreateNot(Ops[3]));
+ Op2 = Builder.CreateZExt(Op2, Int64Ty);
+ Value *Shift = Builder.CreateCall(F, {Op0, Op0, Op2});
+ Value *X = Builder.CreateAnd(Shift, Op3);
+ Value *Y =
+ Builder.CreateAnd(EmitScalarExpr(E->getArg(1)), Builder.CreateNot(Op3));
return Builder.CreateOr(X, Y);
}
// Rotate and insert under mask operation.
// __rlwnm(rs, shift, mask)
// rotl(rs, shift) & mask
case PPC::BI__builtin_ppc_rlwnm: {
- llvm::Type *Ty = Ops[0]->getType();
+ Value *Op0 = EmitScalarExpr(E->getArg(0));
+ llvm::Type *Ty = Op0->getType();
Function *F = CGM.getIntrinsic(Intrinsic::fshl, Ty);
- Value *Shift = Builder.CreateCall(F, {Ops[0], Ops[0], Ops[1]});
- return Builder.CreateAnd(Shift, Ops[2]);
+ Value *Shift =
+ Builder.CreateCall(F, {Op0, Op0, EmitScalarExpr(E->getArg(1))});
+ return Builder.CreateAnd(Shift, EmitScalarExpr(E->getArg(2)));
}
case PPC::BI__builtin_ppc_poppar4:
case PPC::BI__builtin_ppc_poppar8: {
- llvm::Type *ArgType = Ops[0]->getType();
+ Value *Op0 = EmitScalarExpr(E->getArg(0));
+ llvm::Type *ArgType = Op0->getType();
Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType);
- Value *Tmp = Builder.CreateCall(F, Ops[0]);
+ Value *Tmp = Builder.CreateCall(F, Op0);
llvm::Type *ResultType = ConvertType(E->getType());
Value *Result = Builder.CreateAnd(Tmp, llvm::ConstantInt::get(ArgType, 1));
@@ -15642,10 +15653,12 @@
return Result;
}
case PPC::BI__builtin_ppc_cmpb: {
+ Value *Op0 = EmitScalarExpr(E->getArg(0));
+ Value *Op1 = EmitScalarExpr(E->getArg(1));
if (getTarget().getTriple().isPPC64()) {
Function *F =
CGM.getIntrinsic(Intrinsic::ppc_cmpb, {Int64Ty, Int64Ty, Int64Ty});
- return Builder.CreateCall(F, Ops, "cmpb");
+ return Builder.CreateCall(F, {Op0, Op1}, "cmpb");
}
// For 32 bit, emit the code as below:
// %conv = trunc i64 %a to i32
@@ -15663,13 +15676,13 @@
// ret i64 %or
Function *F =
CGM.getIntrinsic(Intrinsic::ppc_cmpb, {Int32Ty, Int32Ty, Int32Ty});
- Value *ArgOneLo = Builder.CreateTrunc(Ops[0], Int32Ty);
- Value *ArgTwoLo = Builder.CreateTrunc(Ops[1], Int32Ty);
+ Value *ArgOneLo = Builder.CreateTrunc(Op0, Int32Ty);
+ Value *ArgTwoLo = Builder.CreateTrunc(Op1, Int32Ty);
Constant *ShiftAmt = ConstantInt::get(Int64Ty, 32);
Value *ArgOneHi =
- Builder.CreateTrunc(Builder.CreateLShr(Ops[0], ShiftAmt), Int32Ty);
+ Builder.CreateTrunc(Builder.CreateLShr(Op0, ShiftAmt), Int32Ty);
Value *ArgTwoHi =
- Builder.CreateTrunc(Builder.CreateLShr(Ops[1], ShiftAmt), Int32Ty);
+ Builder.CreateTrunc(Builder.CreateLShr(Op1, ShiftAmt), Int32Ty);
Value *ResLo = Builder.CreateZExt(
Builder.CreateCall(F, {ArgOneLo, ArgTwoLo}, "cmpb"), Int64Ty);
Value *ResHiShift = Builder.CreateZExt(
@@ -15763,27 +15776,30 @@
return FDiv;
}
case PPC::BI__builtin_ppc_alignx: {
- ConstantInt *AlignmentCI = cast<ConstantInt>(Ops[0]);
+ Value *Op1 = EmitScalarExpr(E->getArg(1));
+ ConstantInt *AlignmentCI = cast<ConstantInt>(EmitScalarExpr(E->getArg(0)));
if (AlignmentCI->getValue().ugt(llvm::Value::MaximumAlignment))
AlignmentCI = ConstantInt::get(AlignmentCI->getType(),
llvm::Value::MaximumAlignment);
- emitAlignmentAssumption(Ops[1], E->getArg(1),
+ emitAlignmentAssumption(Op1, E->getArg(1),
/*The expr loc is sufficient.*/ SourceLocation(),
AlignmentCI, nullptr);
- return Ops[1];
+ return Op1;
}
case PPC::BI__builtin_ppc_rdlam: {
- llvm::Type *Ty = Ops[0]->getType();
- Value *ShiftAmt = Builder.CreateIntCast(Ops[1], Ty, false);
+ Value *Op0 = EmitScalarExpr(E->getArg(0));
+ llvm::Type *Ty = Op0->getType();
+ Value *ShiftAmt =
+ Builder.CreateIntCast(EmitScalarExpr(E->getArg(1)), Ty, false);
Function *F = CGM.getIntrinsic(Intrinsic::fshl, Ty);
- Value *Rotate = Builder.CreateCall(F, {Ops[0], Ops[0], ShiftAmt});
- return Builder.CreateAnd(Rotate, Ops[2]);
+ Value *Rotate = Builder.CreateCall(F, {Op0, Op0, ShiftAmt});
+ return Builder.CreateAnd(Rotate, EmitScalarExpr(E->getArg(2)));
}
case PPC::BI__builtin_ppc_load2r: {
Function *F = CGM.getIntrinsic(Intrinsic::ppc_load2r);
- Ops[0] = Builder.CreateBitCast(Ops[0], Int8PtrTy);
- Value *LoadIntrinsic = Builder.CreateCall(F, Ops);
+ Value *Op0 = Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), Int8PtrTy);
+ Value *LoadIntrinsic = Builder.CreateCall(F, {Op0});
return Builder.CreateTrunc(LoadIntrinsic, Int16Ty);
}
// FMA variations
@@ -15845,11 +15861,14 @@
}
case PPC::BI__builtin_vsx_insertword: {
+ Value *Op0 = EmitScalarExpr(E->getArg(0));
+ Value *Op1 = EmitScalarExpr(E->getArg(1));
+ Value *Op2 = EmitScalarExpr(E->getArg(2));
llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxinsertw);
// Third argument is a compile time constant int. It must be clamped to
// to the range [0, 12].
- ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]);
+ ConstantInt *ArgCI = dyn_cast<ConstantInt>(Op2);
assert(ArgCI &&
"Third arg to xxinsertw intrinsic must be constant integer");
const int64_t MaxIndex = 12;
@@ -15860,40 +15879,38 @@
// word from the first argument, and inserts it in the second argument. The
// instruction extracts the word from its second input register and inserts
// it into its first input register, so swap the first and second arguments.
- std::swap(Ops[0], Ops[1]);
+ std::swap(Op0, Op1);
// Need to cast the second argument from a vector of unsigned int to a
// vector of long long.
- Ops[1] =
- Builder.CreateBitCast(Ops[1], llvm::FixedVectorType::get(Int64Ty, 2));
+ Op1 = Builder.CreateBitCast(Op1, llvm::FixedVectorType::get(Int64Ty, 2));
if (getTarget().isLittleEndian()) {
// Reverse the double words in the vector we will extract from.
- Ops[0] =
- Builder.CreateBitCast(Ops[0], llvm::FixedVectorType::get(Int64Ty, 2));
- Ops[0] = Builder.CreateShuffleVector(Ops[0], Ops[0], ArrayRef<int>{1, 0});
+ Op0 = Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(Int64Ty, 2));
+ Op0 = Builder.CreateShuffleVector(Op0, Op0, ArrayRef<int>{1, 0});
// Reverse the index.
Index = MaxIndex - Index;
}
// Intrinsic expects the first arg to be a vector of int.
- Ops[0] =
- Builder.CreateBitCast(Ops[0], llvm::FixedVectorType::get(Int32Ty, 4));
- Ops[2] = ConstantInt::getSigned(Int32Ty, Index);
- return Builder.CreateCall(F, Ops);
+ Op0 = Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(Int32Ty, 4));
+ Op2 = ConstantInt::getSigned(Int32Ty, Index);
+ return Builder.CreateCall(F, {Op0, Op1, Op2});
}
case PPC::BI__builtin_vsx_extractuword: {
+ Value *Op0 = EmitScalarExpr(E->getArg(0));
+ Value *Op1 = EmitScalarExpr(E->getArg(1));
llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxextractuw);
// Intrinsic expects the first argument to be a vector of doublewords.
- Ops[0] =
- Builder.CreateBitCast(Ops[0], llvm::FixedVectorType::get(Int64Ty, 2));
+ Op0 = Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(Int64Ty, 2));
// The second argument is a compile time constant int that needs to
// be clamped to the range [0, 12].
- ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[1]);
+ ConstantInt *ArgCI = dyn_cast<ConstantInt>(Op1);
assert(ArgCI &&
"Second Arg to xxextractuw intrinsic must be a constant integer!");
const int64_t MaxIndex = 12;
@@ -15902,29 +15919,29 @@
if (getTarget().isLittleEndian()) {
// Reverse the index.
Index = MaxIndex - Index;
- Ops[1] = ConstantInt::getSigned(Int32Ty, Index);
+ Op1 = ConstantInt::getSigned(Int32Ty, Index);
// Emit the call, then reverse the double words of the results vector.
- Value *Call = Builder.CreateCall(F, Ops);
+ Value *Call = Builder.CreateCall(F, {Op0, Op1});
Value *ShuffleCall =
Builder.CreateShuffleVector(Call, Call, ArrayRef<int>{1, 0});
return ShuffleCall;
} else {
- Ops[1] = ConstantInt::getSigned(Int32Ty, Index);
- return Builder.CreateCall(F, Ops);
+ Op1 = ConstantInt::getSigned(Int32Ty, Index);
+ return Builder.CreateCall(F, {Op0, Op1});
}
}
case PPC::BI__builtin_vsx_xxpermdi: {
- ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]);
+ Value *Op0 = EmitScalarExpr(E->getArg(0));
+ Value *Op1 = EmitScalarExpr(E->getArg(1));
+ ConstantInt *ArgCI = dyn_cast<ConstantInt>(EmitScalarExpr(E->getArg(2)));
assert(ArgCI && "Third arg must be constant integer!");
unsigned Index = ArgCI->getZExtValue();
- Ops[0] =
- Builder.CreateBitCast(Ops[0], llvm::FixedVectorType::get(Int64Ty, 2));
- Ops[1] =
- Builder.CreateBitCast(Ops[1], llvm::FixedVectorType::get(Int64Ty, 2));
+ Op0 = Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(Int64Ty, 2));
+ Op1 = Builder.CreateBitCast(Op1, llvm::FixedVectorType::get(Int64Ty, 2));
// Account for endianness by treating this as just a shuffle. So we use the
// same indices for both LE and BE in order to produce expected results in
@@ -15933,21 +15950,20 @@
int ElemIdx1 = 2 + (Index & 1);
int ShuffleElts[2] = {ElemIdx0, ElemIdx1};
- Value *ShuffleCall =
- Builder.CreateShuffleVector(Ops[0], Ops[1], ShuffleElts);
+ Value *ShuffleCall = Builder.CreateShuffleVector(Op0, Op1, ShuffleElts);
QualType BIRetType = E->getType();
auto RetTy = ConvertType(BIRetType);
return Builder.CreateBitCast(ShuffleCall, RetTy);
}
case PPC::BI__builtin_vsx_xxsldwi: {
- ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]);
+ Value *Op0 = EmitScalarExpr(E->getArg(0));
+ Value *Op1 = EmitScalarExpr(E->getArg(1));
+ ConstantInt *ArgCI = dyn_cast<ConstantInt>(EmitScalarExpr(E->getArg(2)));
assert(ArgCI && "Third argument must be a compile time constant");
unsigned Index = ArgCI->getZExtValue() & 0x3;
- Ops[0] =
- Builder.CreateBitCast(Ops[0], llvm::FixedVectorType::get(Int32Ty, 4));
- Ops[1] =
- Builder.CreateBitCast(Ops[1], llvm::FixedVectorType::get(Int32Ty, 4));
+ Op0 = Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(Int32Ty, 4));
+ Op1 = Builder.CreateBitCast(Op1, llvm::FixedVectorType::get(Int32Ty, 4));
// Create a shuffle mask
int ElemIdx0;
@@ -15971,28 +15987,29 @@
}
int ShuffleElts[4] = {ElemIdx0, ElemIdx1, ElemIdx2, ElemIdx3};
- Value *ShuffleCall =
- Builder.CreateShuffleVector(Ops[0], Ops[1], ShuffleElts);
+ Value *ShuffleCall = Builder.CreateShuffleVector(Op0, Op1, ShuffleElts);
QualType BIRetType = E->getType();
auto RetTy = ConvertType(BIRetType);
return Builder.CreateBitCast(ShuffleCall, RetTy);
}
case PPC::BI__builtin_pack_vector_int128: {
+ Value *Op0 = EmitScalarExpr(E->getArg(0));
bool isLittleEndian = getTarget().isLittleEndian();
Value *UndefValue =
- llvm::UndefValue::get(llvm::FixedVectorType::get(Ops[0]->getType(), 2));
+ llvm::UndefValue::get(llvm::FixedVectorType::get(Op0->getType(), 2));
Value *Res = Builder.CreateInsertElement(
- UndefValue, Ops[0], (uint64_t)(isLittleEndian ? 1 : 0));
- Res = Builder.CreateInsertElement(Res, Ops[1],
+ UndefValue, Op0, (uint64_t)(isLittleEndian ? 1 : 0));
+ Res = Builder.CreateInsertElement(Res, EmitScalarExpr(E->getArg(1)),
(uint64_t)(isLittleEndian ? 0 : 1));
return Builder.CreateBitCast(Res, ConvertType(E->getType()));
}
case PPC::BI__builtin_unpack_vector_int128: {
- ConstantInt *Index = cast<ConstantInt>(Ops[1]);
+ Value *Op0 = EmitScalarExpr(E->getArg(0));
+ ConstantInt *Index = cast<ConstantInt>(EmitScalarExpr(E->getArg(1)));
Value *Unpacked = Builder.CreateBitCast(
- Ops[0], llvm::FixedVectorType::get(ConvertType(E->getType()), 2));
+ Op0, llvm::FixedVectorType::get(ConvertType(E->getType()), 2));
if (getTarget().isLittleEndian())
Index = ConstantInt::get(Index->getType(), 1 - Index->getZExtValue());
@@ -16002,9 +16019,9 @@
case PPC::BI__builtin_ppc_sthcx: {
llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_sthcx);
- Ops[0] = Builder.CreateBitCast(Ops[0], Int8PtrTy);
- Ops[1] = Builder.CreateSExt(Ops[1], Int32Ty);
- return Builder.CreateCall(F, Ops);
+ Value *Op0 = Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), Int8PtrTy);
+ Value *Op1 = Builder.CreateSExt(EmitScalarExpr(E->getArg(1)), Int32Ty);
+ return Builder.CreateCall(F, {Op0, Op1});
}
// The PPC MMA builtins take a pointer to a __vector_quad as an argument.
@@ -16017,6 +16034,9 @@
case PPC::BI__builtin_##Name:
#include "clang/Basic/BuiltinsPPC.def"
{
+ SmallVector<Value *, 4> Ops;
+ for (unsigned i = 0, e = E->getNumArgs(); i != e; i++)
+ Ops.push_back(EmitScalarExpr(E->getArg(i)));
// The first argument of these two builtins is a pointer used to store their
// result. However, the llvm intrinsics return their result in multiple
// return values. So, here we emit code extracting these values from the
@@ -16101,8 +16121,9 @@
QualType AtomicTy = E->getArg(0)->getType()->getPointeeType();
LValue LV = MakeAddrLValue(Addr, AtomicTy);
auto Pair = EmitAtomicCompareExchange(
- LV, RValue::get(OldVal), RValue::get(Ops[2]), E->getExprLoc(),
- llvm::AtomicOrdering::Monotonic, llvm::AtomicOrdering::Monotonic, true);
+ LV, RValue::get(OldVal), RValue::get(EmitScalarExpr(E->getArg(2))),
+ E->getExprLoc(), llvm::AtomicOrdering::Monotonic,
+ llvm::AtomicOrdering::Monotonic, true);
// Unlike c11's atomic_compare_exchange, accroding to
// https://www.ibm.com/docs/en/xl-c-and-cpp-aix/16.1?topic=functions-compare-swap-compare-swaplp
// > In either case, the contents of the memory location specified by addr
@@ -16145,34 +16166,37 @@
? Int32Ty
: Int64Ty;
Function *F = CGM.getIntrinsic(Intrinsic::ppc_mfspr, RetType);
- return Builder.CreateCall(F, Ops);
+ return Builder.CreateCall(F, {EmitScalarExpr(E->getArg(0))});
}
case PPC::BI__builtin_ppc_mtspr: {
llvm::Type *RetType = CGM.getDataLayout().getTypeSizeInBits(VoidPtrTy) == 32
? Int32Ty
: Int64Ty;
Function *F = CGM.getIntrinsic(Intrinsic::ppc_mtspr, RetType);
- return Builder.CreateCall(F, Ops);
+ return Builder.CreateCall(
+ F, {EmitScalarExpr(E->getArg(0)), EmitScalarExpr(E->getArg(1))});
}
case PPC::BI__builtin_ppc_popcntb: {
Value *ArgValue = EmitScalarExpr(E->getArg(0));
llvm::Type *ArgType = ArgValue->getType();
Function *F = CGM.getIntrinsic(Intrinsic::ppc_popcntb, {ArgType, ArgType});
- return Builder.CreateCall(F, Ops, "popcntb");
+ return Builder.CreateCall(F, {ArgValue}, "popcntb");
}
case PPC::BI__builtin_ppc_mtfsf: {
// The builtin takes a uint32 that needs to be cast to an
// f64 to be passed to the intrinsic.
- Value *Cast = Builder.CreateUIToFP(Ops[1], DoubleTy);
+ Value *Cast = Builder.CreateUIToFP(EmitScalarExpr(E->getArg(1)), DoubleTy);
llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_mtfsf);
- return Builder.CreateCall(F, {Ops[0], Cast}, "");
+ return Builder.CreateCall(F, {EmitScalarExpr(E->getArg(0)), Cast}, "");
}
case PPC::BI__builtin_ppc_swdiv_nochk:
case PPC::BI__builtin_ppc_swdivs_nochk: {
FastMathFlags FMF = Builder.getFastMathFlags();
Builder.getFastMathFlags().setFast();
- Value *FDiv = Builder.CreateFDiv(Ops[0], Ops[1], "swdiv_nochk");
+ Value *FDiv =
+ Builder.CreateFDiv(EmitScalarExpr(E->getArg(0)),
+ EmitScalarExpr(E->getArg(1)), "swdiv_nochk");
Builder.getFastMathFlags() &= (FMF);
return FDiv;
}
@@ -16212,7 +16236,8 @@
Intrinsic::experimental_constrained_sqrt))
.getScalarVal();
case PPC::BI__builtin_ppc_test_data_class: {
- llvm::Type *ArgType = EmitScalarExpr(E->getArg(0))->getType();
+ Value *Op0 = EmitScalarExpr(E->getArg(0));
+ llvm::Type *ArgType = Op0->getType();
unsigned IntrinsicID;
if (ArgType->isDoubleTy())
IntrinsicID = Intrinsic::ppc_test_data_class_d;
@@ -16220,12 +16245,14 @@
IntrinsicID = Intrinsic::ppc_test_data_class_f;
else
llvm_unreachable("Invalid Argument Type");
- return Builder.CreateCall(CGM.getIntrinsic(IntrinsicID), Ops,
+ return Builder.CreateCall(CGM.getIntrinsic(IntrinsicID),
+ {Op0, EmitScalarExpr(E->getArg(1))},
"test_data_class");
}
case PPC::BI__builtin_ppc_swdiv:
case PPC::BI__builtin_ppc_swdivs:
- return Builder.CreateFDiv(Ops[0], Ops[1], "swdiv");
+ return Builder.CreateFDiv(EmitScalarExpr(E->getArg(0)),
+ EmitScalarExpr(E->getArg(1)), "swdiv");
}
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits