quinnp updated this revision to Diff 416917. quinnp added a comment. Fixing a failing test case.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D121637/new/ 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-math.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-math.c =================================================================== --- clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-math.c +++ clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-math.c @@ -95,7 +95,6 @@ // CHECK-LABEL: @fnmsub( // CHECK: [[D_ADDR:%.*]] = alloca double, align 8 // CHECK-NEXT: store double [[D:%.*]], double* [[D_ADDR]], align 8 -// CHECK-COUNT-3: load double, double* [[D_ADDR]], align 8 // CHECK-NEXT: [[TMP0:%.*]] = load double, double* [[D_ADDR]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = load double, double* [[D_ADDR]], align 8 // CHECK-NEXT: [[TMP2:%.*]] = load double, double* [[D_ADDR]], align 8 @@ -109,7 +108,6 @@ // CHECK-LABEL: @fnmsubs( // CHECK: [[F_ADDR:%.*]] = alloca float, align 4 // CHECK-NEXT: store float [[F:%.*]], float* [[F_ADDR]], align 4 -// CHECK-COUNT-3: load float, float* [[F_ADDR]], align 4 // CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[F_ADDR]], align 4 // CHECK-NEXT: [[TMP1:%.*]] = load float, float* [[F_ADDR]], align 4 // CHECK-NEXT: [[TMP2:%.*]] = load float, float* [[F_ADDR]], align 4 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); @@ -15356,13 +15355,15 @@ // 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(); + Value *Op0 = EmitScalarExpr(E->getArg(0)); + Value *Op1 = EmitScalarExpr(E->getArg(1)); + 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 cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits