Eliminate instances of `EmitScalarExpr(E->getArg(n))` in EmitX86BuiltinExpr().

EmitX86BuiltinExpr() emits all args into Ops at the beginning, so don't do that
work again.

This changes behavior: If e.g. ++a was passed as an arg, we incremented a twice
previously. This change fixes that bug.

https://reviews.llvm.org/D50979

llvm-svn: 340348
This commit is contained in:
Nico Weber 2018-08-21 22:19:55 +00:00
parent 22d1a2789a
commit 14a577bfd1
3 changed files with 46 additions and 34 deletions

View File

@ -10528,14 +10528,11 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
llvm::Type *Int128PtrTy = Int128Ty->getPointerTo();
Value *Destination =
Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), Int128PtrTy);
Value *ExchangeHigh128 =
Builder.CreateZExt(EmitScalarExpr(E->getArg(1)), Int128Ty);
Value *ExchangeLow128 =
Builder.CreateZExt(EmitScalarExpr(E->getArg(2)), Int128Ty);
Address ComparandResult(
Builder.CreateBitCast(EmitScalarExpr(E->getArg(3)), Int128PtrTy),
getContext().toCharUnitsFromBits(128));
Builder.CreateBitCast(Ops[0], Int128PtrTy);
Value *ExchangeHigh128 = Builder.CreateZExt(Ops[1], Int128Ty);
Value *ExchangeLow128 = Builder.CreateZExt(Ops[2], Int128Ty);
Address ComparandResult(Builder.CreateBitCast(Ops[3], Int128PtrTy),
getContext().toCharUnitsFromBits(128));
Value *Exchange = Builder.CreateOr(
Builder.CreateShl(ExchangeHigh128, 64, "", false, false),
@ -10586,8 +10583,8 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
case X86::BI__readfsdword:
case X86::BI__readfsqword: {
llvm::Type *IntTy = ConvertType(E->getType());
Value *Ptr = Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)),
llvm::PointerType::get(IntTy, 257));
Value *Ptr =
Builder.CreateIntToPtr(Ops[0], llvm::PointerType::get(IntTy, 257));
LoadInst *Load = Builder.CreateAlignedLoad(
IntTy, Ptr, getContext().getTypeAlignInChars(E->getType()));
Load->setVolatile(true);
@ -10598,8 +10595,8 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
case X86::BI__readgsdword:
case X86::BI__readgsqword: {
llvm::Type *IntTy = ConvertType(E->getType());
Value *Ptr = Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)),
llvm::PointerType::get(IntTy, 256));
Value *Ptr =
Builder.CreateIntToPtr(Ops[0], llvm::PointerType::get(IntTy, 256));
LoadInst *Load = Builder.CreateAlignedLoad(
IntTy, Ptr, getContext().getTypeAlignInChars(E->getType()));
Load->setVolatile(true);

View File

@ -416,14 +416,21 @@ __int64 test_InterlockedCompareExchange64(__int64 volatile *Destination, __int64
// CHECK: }
#if defined(__x86_64__)
unsigned char test_InterlockedCompareExchange128(__int64 volatile *Destination, __int64 ExchangeHigh, __int64 ExchangeLow, __int64* ComparandResult) {
return _InterlockedCompareExchange128(Destination, ExchangeHigh, ExchangeLow, ComparandResult);
unsigned char test_InterlockedCompareExchange128(
__int64 volatile *Destination, __int64 ExchangeHigh,
__int64 ExchangeLow, __int64 *ComparandResult) {
return _InterlockedCompareExchange128(++Destination, ++ExchangeHigh,
++ExchangeLow, ++ComparandResult);
}
// CHECK-X64: define{{.*}}i8 @test_InterlockedCompareExchange128(i64*{{[a-z_ ]*}}%Destination, i64{{[a-z_ ]*}}%ExchangeHigh, i64{{[a-z_ ]*}}%ExchangeLow, i64*{{[a-z_ ]*}}%ComparandResult){{.*}}{
// CHECK-X64: [[DST:%[0-9]+]] = bitcast i64* %Destination to i128*
// CHECK-X64: [[EH:%[0-9]+]] = zext i64 %ExchangeHigh to i128
// CHECK-X64: [[EL:%[0-9]+]] = zext i64 %ExchangeLow to i128
// CHECK-X64: [[CNR:%[0-9]+]] = bitcast i64* %ComparandResult to i128*
// CHECK-X64: %incdec.ptr = getelementptr inbounds i64, i64* %Destination, i64 1
// CHECK-X64: %inc = add nsw i64 %ExchangeHigh, 1
// CHECK-X64: %inc1 = add nsw i64 %ExchangeLow, 1
// CHECK-X64: %incdec.ptr2 = getelementptr inbounds i64, i64* %ComparandResult, i64 1
// CHECK-X64: [[DST:%[0-9]+]] = bitcast i64* %incdec.ptr to i128*
// CHECK-X64: [[EH:%[0-9]+]] = zext i64 %inc to i128
// CHECK-X64: [[EL:%[0-9]+]] = zext i64 %inc1 to i128
// CHECK-X64: [[CNR:%[0-9]+]] = bitcast i64* %incdec.ptr2 to i128*
// CHECK-X64: [[EHS:%[0-9]+]] = shl nuw i128 [[EH]], 64
// CHECK-X64: [[EXP:%[0-9]+]] = or i128 [[EHS]], [[EL]]
// CHECK-X64: [[ORG:%[0-9]+]] = load i128, i128* [[CNR]], align 16

View File

@ -7,34 +7,38 @@
#if defined(__i386__)
char test__readfsbyte(unsigned long Offset) {
return __readfsbyte(Offset);
return __readfsbyte(++Offset);
}
// CHECK-I386-LABEL: define dso_local signext i8 @test__readfsbyte(i32 %Offset)
// CHECK-I386: [[PTR:%[0-9]+]] = inttoptr i32 %Offset to i8 addrspace(257)*
// CHECK-I386: %inc = add i32 %Offset, 1
// CHECK-I386: [[PTR:%[0-9]+]] = inttoptr i32 %inc to i8 addrspace(257)*
// CHECK-I386: [[VALUE:%[0-9]+]] = load volatile i8, i8 addrspace(257)* [[PTR]], align 1
// CHECK-I386: ret i8 [[VALUE:%[0-9]+]]
short test__readfsword(unsigned long Offset) {
return __readfsword(Offset);
return __readfsword(++Offset);
}
// CHECK-I386-LABEL: define dso_local signext i16 @test__readfsword(i32 %Offset)
// CHECK-I386: [[PTR:%[0-9]+]] = inttoptr i32 %Offset to i16 addrspace(257)*
// CHECK-I386: %inc = add i32 %Offset, 1
// CHECK-I386: [[PTR:%[0-9]+]] = inttoptr i32 %inc to i16 addrspace(257)*
// CHECK-I386: [[VALUE:%[0-9]+]] = load volatile i16, i16 addrspace(257)* [[PTR]], align 2
// CHECK-I386: ret i16 [[VALUE:%[0-9]+]]
long test__readfsdword(unsigned long Offset) {
return __readfsdword(Offset);
return __readfsdword(++Offset);
}
// CHECK-I386-LABEL: define dso_local i32 @test__readfsdword(i32 %Offset)
// CHECK-I386: [[PTR:%[0-9]+]] = inttoptr i32 %Offset to i32 addrspace(257)*
// CHECK-I386: %inc = add i32 %Offset, 1
// CHECK-I386: [[PTR:%[0-9]+]] = inttoptr i32 %inc to i32 addrspace(257)*
// CHECK-I386: [[VALUE:%[0-9]+]] = load volatile i32, i32 addrspace(257)* [[PTR]], align 4
// CHECK-I386: ret i32 [[VALUE:%[0-9]+]]
long long test__readfsqword(unsigned long Offset) {
return __readfsqword(Offset);
return __readfsqword(++Offset);
}
// CHECK-I386-LABEL: define dso_local i64 @test__readfsqword(i32 %Offset)
// CHECK-I386: [[PTR:%[0-9]+]] = inttoptr i32 %Offset to i64 addrspace(257)*
// CHECK-I386: %inc = add i32 %Offset, 1
// CHECK-I386: [[PTR:%[0-9]+]] = inttoptr i32 %inc to i64 addrspace(257)*
// CHECK-I386: [[VALUE:%[0-9]+]] = load volatile i64, i64 addrspace(257)* [[PTR]], align 8
// CHECK-I386: ret i64 [[VALUE:%[0-9]+]]
#endif
@ -60,37 +64,41 @@ unsigned __int64 test__emulu(unsigned int a, unsigned int b) {
#if defined(__x86_64__)
char test__readgsbyte(unsigned long Offset) {
return __readgsbyte(Offset);
return __readgsbyte(++Offset);
}
// CHECK-X64-LABEL: define dso_local i8 @test__readgsbyte(i32 %Offset)
// CHECK-X64: [[ZEXT:%[0-9]+]] = zext i32 %Offset to i64
// CHECK-X64: %inc = add i32 %Offset, 1
// CHECK-X64: [[ZEXT:%[0-9]+]] = zext i32 %inc to i64
// CHECK-X64: [[PTR:%[0-9]+]] = inttoptr i64 [[ZEXT]] to i8 addrspace(256)*
// CHECK-X64: [[VALUE:%[0-9]+]] = load volatile i8, i8 addrspace(256)* [[PTR]], align 1
// CHECK-X64: ret i8 [[VALUE:%[0-9]+]]
short test__readgsword(unsigned long Offset) {
return __readgsword(Offset);
return __readgsword(++Offset);
}
// CHECK-X64-LABEL: define dso_local i16 @test__readgsword(i32 %Offset)
// CHECK-X64: [[ZEXT:%[0-9]+]] = zext i32 %Offset to i64
// CHECK-X64: %inc = add i32 %Offset, 1
// CHECK-X64: [[ZEXT:%[0-9]+]] = zext i32 %inc to i64
// CHECK-X64: [[PTR:%[0-9]+]] = inttoptr i64 [[ZEXT]] to i16 addrspace(256)*
// CHECK-X64: [[VALUE:%[0-9]+]] = load volatile i16, i16 addrspace(256)* [[PTR]], align 2
// CHECK-X64: ret i16 [[VALUE:%[0-9]+]]
long test__readgsdword(unsigned long Offset) {
return __readgsdword(Offset);
return __readgsdword(++Offset);
}
// CHECK-X64-LABEL: define dso_local i32 @test__readgsdword(i32 %Offset)
// CHECK-X64: [[ZEXT:%[0-9]+]] = zext i32 %Offset to i64
// CHECK-X64: %inc = add i32 %Offset, 1
// CHECK-X64: [[ZEXT:%[0-9]+]] = zext i32 %inc to i64
// CHECK-X64: [[PTR:%[0-9]+]] = inttoptr i64 [[ZEXT]] to i32 addrspace(256)*
// CHECK-X64: [[VALUE:%[0-9]+]] = load volatile i32, i32 addrspace(256)* [[PTR]], align 4
// CHECK-X64: ret i32 [[VALUE:%[0-9]+]]
long long test__readgsqword(unsigned long Offset) {
return __readgsqword(Offset);
return __readgsqword(++Offset);
}
// CHECK-X64-LABEL: define dso_local i64 @test__readgsqword(i32 %Offset)
// CHECK-X64: [[ZEXT:%[0-9]+]] = zext i32 %Offset to i64
// CHECK-X64: %inc = add i32 %Offset, 1
// CHECK-X64: [[ZEXT:%[0-9]+]] = zext i32 %inc to i64
// CHECK-X64: [[PTR:%[0-9]+]] = inttoptr i64 [[ZEXT]] to i64 addrspace(256)*
// CHECK-X64: [[VALUE:%[0-9]+]] = load volatile i64, i64 addrspace(256)* [[PTR]], align 8
// CHECK-X64: ret i64 [[VALUE:%[0-9]+]]