forked from OSchip/llvm-project
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:
parent
22d1a2789a
commit
14a577bfd1
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]+]]
|
||||
|
|
Loading…
Reference in New Issue