Index: clang/lib/CodeGen/CGBuiltin.cpp =================================================================== --- clang/lib/CodeGen/CGBuiltin.cpp +++ clang/lib/CodeGen/CGBuiltin.cpp @@ -10480,14 +10480,11 @@ 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), @@ -10538,8 +10535,8 @@ 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); @@ -10550,8 +10547,8 @@ 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); Index: clang/test/CodeGen/ms-intrinsics.c =================================================================== --- clang/test/CodeGen/ms-intrinsics.c +++ clang/test/CodeGen/ms-intrinsics.c @@ -416,14 +416,21 @@ // 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 Index: clang/test/CodeGen/ms-x86-intrinsics.c =================================================================== --- clang/test/CodeGen/ms-x86-intrinsics.c +++ clang/test/CodeGen/ms-x86-intrinsics.c @@ -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 @@ #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]+]]