Index: clang/lib/CodeGen/CGBuiltin.cpp =================================================================== --- clang/lib/CodeGen/CGBuiltin.cpp +++ clang/lib/CodeGen/CGBuiltin.cpp @@ -1060,7 +1060,10 @@ llvm::InlineAsm *IA = llvm::InlineAsm::get(FTy, Asm, Constraints, /*hasSideEffects=*/true); - return CGF.Builder.CreateCall(IA, {Addr}); + llvm::CallInst *CI = CGF.Builder.CreateCall(IA, {Addr}); + CI->addParamAttr(0, Attribute::get( + CGF.getLLVMContext(), Attribute::ElementType, RetType)); + return CI; } namespace { Index: clang/lib/CodeGen/CGObjCMac.cpp =================================================================== --- clang/lib/CodeGen/CGObjCMac.cpp +++ clang/lib/CodeGen/CGObjCMac.cpp @@ -4370,7 +4370,11 @@ void FragileHazards::emitWriteHazard() { if (Locals.empty()) return; - CGF.EmitNounwindRuntimeCall(WriteHazard, Locals); + llvm::CallInst *Call = CGF.EmitNounwindRuntimeCall(WriteHazard, Locals); + for (auto Pair : llvm::enumerate(Locals)) + Call->addParamAttr(Pair.index(), llvm::Attribute::get( + CGF.getLLVMContext(), llvm::Attribute::ElementType, + cast(Pair.value())->getAllocatedType())); } void FragileHazards::emitReadHazard(CGBuilderTy &Builder) { @@ -4378,6 +4382,10 @@ llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals); call->setDoesNotThrow(); call->setCallingConv(CGF.getRuntimeCC()); + for (auto Pair : llvm::enumerate(Locals)) + call->addParamAttr(Pair.index(), llvm::Attribute::get( + Builder.getContext(), llvm::Attribute::ElementType, + cast(Pair.value())->getAllocatedType())); } /// Emit read hazards in all the protected blocks, i.e. all the blocks Index: clang/lib/CodeGen/CGStmt.cpp =================================================================== --- clang/lib/CodeGen/CGStmt.cpp +++ clang/lib/CodeGen/CGStmt.cpp @@ -2109,42 +2109,36 @@ return (EarlyClobber ? "&{" : "{") + Register.str() + "}"; } -llvm::Value* +std::pair CodeGenFunction::EmitAsmInputLValue(const TargetInfo::ConstraintInfo &Info, LValue InputValue, QualType InputType, std::string &ConstraintStr, SourceLocation Loc) { - llvm::Value *Arg; if (Info.allowsRegister() || !Info.allowsMemory()) { - if (CodeGenFunction::hasScalarEvaluationKind(InputType)) { - Arg = EmitLoadOfLValue(InputValue, Loc).getScalarVal(); - } else { - llvm::Type *Ty = ConvertType(InputType); - uint64_t Size = CGM.getDataLayout().getTypeSizeInBits(Ty); - if ((Size <= 64 && llvm::isPowerOf2_64(Size)) || - getTargetHooks().isScalarizableAsmOperand(*this, Ty)) { - Ty = llvm::IntegerType::get(getLLVMContext(), Size); - Ty = llvm::PointerType::getUnqual(Ty); - - Arg = Builder.CreateLoad( - Builder.CreateBitCast(InputValue.getAddress(*this), Ty)); - } else { - Arg = InputValue.getPointer(*this); - ConstraintStr += '*'; - } + if (CodeGenFunction::hasScalarEvaluationKind(InputType)) + return {EmitLoadOfLValue(InputValue, Loc).getScalarVal(), nullptr}; + + llvm::Type *Ty = ConvertType(InputType); + uint64_t Size = CGM.getDataLayout().getTypeSizeInBits(Ty); + if ((Size <= 64 && llvm::isPowerOf2_64(Size)) || + getTargetHooks().isScalarizableAsmOperand(*this, Ty)) { + Ty = llvm::IntegerType::get(getLLVMContext(), Size); + Ty = llvm::PointerType::getUnqual(Ty); + + return {Builder.CreateLoad( + Builder.CreateBitCast(InputValue.getAddress(*this), Ty)), nullptr}; } - } else { - Arg = InputValue.getPointer(*this); - ConstraintStr += '*'; } - return Arg; + Address Addr = InputValue.getAddress(*this); + ConstraintStr += '*'; + return {Addr.getPointer(), Addr.getElementType()}; } -llvm::Value* CodeGenFunction::EmitAsmInput( - const TargetInfo::ConstraintInfo &Info, - const Expr *InputExpr, - std::string &ConstraintStr) { +std::pair +CodeGenFunction::EmitAsmInput(const TargetInfo::ConstraintInfo &Info, + const Expr *InputExpr, + std::string &ConstraintStr) { // If this can't be a register or memory, i.e., has to be a constant // (immediate or symbolic), try to emit it as such. if (!Info.allowsRegister() && !Info.allowsMemory()) { @@ -2155,19 +2149,20 @@ llvm::APSInt IntResult; if (EVResult.Val.toIntegralConstant(IntResult, InputExpr->getType(), getContext())) - return llvm::ConstantInt::get(getLLVMContext(), IntResult); + return {llvm::ConstantInt::get(getLLVMContext(), IntResult), nullptr}; } Expr::EvalResult Result; if (InputExpr->EvaluateAsInt(Result, getContext())) - return llvm::ConstantInt::get(getLLVMContext(), Result.Val.getInt()); + return {llvm::ConstantInt::get(getLLVMContext(), Result.Val.getInt()), + nullptr}; } if (Info.allowsRegister() || !Info.allowsMemory()) if (CodeGenFunction::hasScalarEvaluationKind(InputExpr->getType())) - return EmitScalarExpr(InputExpr); + return {EmitScalarExpr(InputExpr), nullptr}; if (InputExpr->getStmtClass() == Expr::CXXThisExprClass) - return EmitScalarExpr(InputExpr); + return {EmitScalarExpr(InputExpr), nullptr}; InputExpr = InputExpr->IgnoreParenNoopCasts(getContext()); LValue Dest = EmitLValue(InputExpr); return EmitAsmInputLValue(Info, Dest, InputExpr->getType(), ConstraintStr, @@ -2209,6 +2204,7 @@ bool HasUnwindClobber, bool ReadOnly, bool ReadNone, bool NoMerge, const AsmStmt &S, const std::vector &ResultRegTypes, + const std::vector &ArgElemTypes, CodeGenFunction &CGF, std::vector &RegResults) { if (!HasUnwindClobber) @@ -2224,6 +2220,15 @@ Result.addFnAttr(llvm::Attribute::ReadOnly); } + // Add elementtype attribute for indirect constraints. + for (auto Pair : llvm::enumerate(ArgElemTypes)) { + if (Pair.value()) { + auto Attr = llvm::Attribute::get( + CGF.getLLVMContext(), llvm::Attribute::ElementType, Pair.value()); + Result.addParamAttr(Pair.index(), Attr); + } + } + // Slap the source location of the inline asm into a !srcloc metadata on the // call. if (const auto *gccAsmStmt = dyn_cast(&S)) @@ -2291,6 +2296,7 @@ std::vector ResultRegTypes; std::vector ResultTruncRegTypes; std::vector ArgTypes; + std::vector ArgElemTypes; std::vector Args; llvm::BitVector ResultTypeRequiresCast; @@ -2298,6 +2304,7 @@ std::string InOutConstraints; std::vector InOutArgs; std::vector InOutArgTypes; + std::vector InOutArgElemTypes; // Keep track of out constraints for tied input operand. std::vector OutputConstraints; @@ -2399,21 +2406,19 @@ std::max((uint64_t)LargestVectorWidth, VT->getPrimitiveSizeInBits().getKnownMinSize()); } else { - llvm::Type *DestAddrTy = Dest.getAddress(*this).getType(); - llvm::Value *DestPtr = Dest.getPointer(*this); + Address DestAddr = Dest.getAddress(*this); // Matrix types in memory are represented by arrays, but accessed through // vector pointers, with the alignment specified on the access operation. // For inline assembly, update pointer arguments to use vector pointers. // Otherwise there will be a mis-match if the matrix is also an // input-argument which is represented as vector. - if (isa(OutExpr->getType().getCanonicalType())) { - DestAddrTy = llvm::PointerType::get( - ConvertType(OutExpr->getType()), - cast(DestAddrTy)->getAddressSpace()); - DestPtr = Builder.CreateBitCast(DestPtr, DestAddrTy); - } - ArgTypes.push_back(DestAddrTy); - Args.push_back(DestPtr); + if (isa(OutExpr->getType().getCanonicalType())) + DestAddr = Builder.CreateElementBitCast( + DestAddr, ConvertType(OutExpr->getType())); + + ArgTypes.push_back(DestAddr.getType()); + ArgElemTypes.push_back(DestAddr.getElementType()); + Args.push_back(DestAddr.getPointer()); Constraints += "=*"; Constraints += OutputConstraint; ReadOnly = ReadNone = false; @@ -2423,9 +2428,11 @@ InOutConstraints += ','; const Expr *InputExpr = S.getOutputExpr(i); - llvm::Value *Arg = EmitAsmInputLValue(Info, Dest, InputExpr->getType(), - InOutConstraints, - InputExpr->getExprLoc()); + llvm::Value *Arg; + llvm::Type *ArgElemType; + std::tie(Arg, ArgElemType) = EmitAsmInputLValue( + Info, Dest, InputExpr->getType(), InOutConstraints, + InputExpr->getExprLoc()); if (llvm::Type* AdjTy = getTargetHooks().adjustInlineAsmType(*this, OutputConstraint, @@ -2444,6 +2451,7 @@ InOutConstraints += OutputConstraint; InOutArgTypes.push_back(Arg->getType()); + InOutArgElemTypes.push_back(ArgElemType); InOutArgs.push_back(Arg); } } @@ -2483,7 +2491,9 @@ getTarget(), CGM, S, false /* No EarlyClobber */); std::string ReplaceConstraint (InputConstraint); - llvm::Value *Arg = EmitAsmInput(Info, InputExpr, Constraints); + llvm::Value *Arg; + llvm::Type *ArgElemType; + std::tie(Arg, ArgElemType) = EmitAsmInput(Info, InputExpr, Constraints); // If this input argument is tied to a larger output result, extend the // input to be the same size as the output. The LLVM backend wants to see @@ -2528,6 +2538,7 @@ VT->getPrimitiveSizeInBits().getKnownMinSize()); ArgTypes.push_back(Arg->getType()); + ArgElemTypes.push_back(ArgElemType); Args.push_back(Arg); Constraints += InputConstraint; } @@ -2546,6 +2557,7 @@ llvm::BlockAddress::get(CurFn, Dest.getBlock()); Args.push_back(BA); ArgTypes.push_back(BA->getType()); + ArgElemTypes.push_back(nullptr); if (!Constraints.empty()) Constraints += ','; Constraints += 'X'; @@ -2557,6 +2569,7 @@ // Append the "input" part of inout constraints last. for (unsigned i = 0, e = InOutArgs.size(); i != e; i++) { ArgTypes.push_back(InOutArgTypes[i]); + ArgElemTypes.push_back(InOutArgElemTypes[i]); Args.push_back(InOutArgs[i]); } Constraints += InOutConstraints; @@ -2647,18 +2660,18 @@ EmitBlock(Fallthrough); UpdateAsmCallInst(cast(*Result), HasSideEffect, false, ReadOnly, ReadNone, InNoMergeAttributedStmt, S, - ResultRegTypes, *this, RegResults); + ResultRegTypes, ArgElemTypes, *this, RegResults); } else if (HasUnwindClobber) { llvm::CallBase *Result = EmitCallOrInvoke(IA, Args, ""); UpdateAsmCallInst(*Result, HasSideEffect, true, ReadOnly, ReadNone, - InNoMergeAttributedStmt, S, ResultRegTypes, *this, - RegResults); + InNoMergeAttributedStmt, S, ResultRegTypes, ArgElemTypes, + *this, RegResults); } else { llvm::CallInst *Result = Builder.CreateCall(IA, Args, getBundlesForFunclet(IA)); UpdateAsmCallInst(cast(*Result), HasSideEffect, false, ReadOnly, ReadNone, InNoMergeAttributedStmt, S, - ResultRegTypes, *this, RegResults); + ResultRegTypes, ArgElemTypes, *this, RegResults); } assert(RegResults.size() == ResultRegTypes.size()); Index: clang/lib/CodeGen/CodeGenFunction.h =================================================================== --- clang/lib/CodeGen/CodeGenFunction.h +++ clang/lib/CodeGen/CodeGenFunction.h @@ -4677,13 +4677,14 @@ SmallVectorImpl &IRCallArgs, unsigned &IRCallArgPos); - llvm::Value* EmitAsmInput(const TargetInfo::ConstraintInfo &Info, - const Expr *InputExpr, std::string &ConstraintStr); - - llvm::Value* EmitAsmInputLValue(const TargetInfo::ConstraintInfo &Info, - LValue InputValue, QualType InputType, - std::string &ConstraintStr, - SourceLocation Loc); + std::pair + EmitAsmInput(const TargetInfo::ConstraintInfo &Info, const Expr *InputExpr, + std::string &ConstraintStr); + + std::pair + EmitAsmInputLValue(const TargetInfo::ConstraintInfo &Info, LValue InputValue, + QualType InputType, std::string &ConstraintStr, + SourceLocation Loc); /// Attempts to statically evaluate the object size of E. If that /// fails, emits code to figure the size of E out for us. This is Index: clang/test/CodeGen/RISCV/riscv-inline-asm.c =================================================================== --- clang/test/CodeGen/RISCV/riscv-inline-asm.c +++ clang/test/CodeGen/RISCV/riscv-inline-asm.c @@ -41,7 +41,7 @@ void test_A(int *p) { // CHECK-LABEL: define{{.*}} void @test_A(i32* %p) -// CHECK: call void asm sideeffect "", "*A"(i32* %p) +// CHECK: call void asm sideeffect "", "*A"(i32* elementtype(i32) %p) asm volatile("" :: "A"(*p)); } Index: clang/test/CodeGen/SystemZ/systemz-inline-asm.c =================================================================== --- clang/test/CodeGen/SystemZ/systemz-inline-asm.c +++ clang/test/CodeGen/SystemZ/systemz-inline-asm.c @@ -6,31 +6,31 @@ void test_store_m(unsigned int i) { asm("st %1, %0" : "=m" (gi) : "r" (i)); // CHECK-LABEL: define{{.*}} void @test_store_m(i32 zeroext %i) -// CHECK: call void asm "st $1, $0", "=*m,r"(i32* nonnull @gi, i32 %i) +// CHECK: call void asm "st $1, $0", "=*m,r"(i32* nonnull elementtype(i32) @gi, i32 %i) } void test_store_Q(unsigned int i) { asm("st %1, %0" : "=Q" (gi) : "r" (i)); // CHECK-LABEL: define{{.*}} void @test_store_Q(i32 zeroext %i) -// CHECK: call void asm "st $1, $0", "=*Q,r"(i32* nonnull @gi, i32 %i) +// CHECK: call void asm "st $1, $0", "=*Q,r"(i32* nonnull elementtype(i32) @gi, i32 %i) } void test_store_R(unsigned int i) { asm("st %1, %0" : "=R" (gi) : "r" (i)); // CHECK-LABEL: define{{.*}} void @test_store_R(i32 zeroext %i) -// CHECK: call void asm "st $1, $0", "=*R,r"(i32* nonnull @gi, i32 %i) +// CHECK: call void asm "st $1, $0", "=*R,r"(i32* nonnull elementtype(i32) @gi, i32 %i) } void test_store_S(unsigned int i) { asm("st %1, %0" : "=S" (gi) : "r" (i)); // CHECK-LABEL: define{{.*}} void @test_store_S(i32 zeroext %i) -// CHECK: call void asm "st $1, $0", "=*S,r"(i32* nonnull @gi, i32 %i) +// CHECK: call void asm "st $1, $0", "=*S,r"(i32* nonnull elementtype(i32) @gi, i32 %i) } void test_store_T(unsigned int i) { asm("st %1, %0" : "=T" (gi) : "r" (i)); // CHECK-LABEL: define{{.*}} void @test_store_T(i32 zeroext %i) -// CHECK: call void asm "st $1, $0", "=*T,r"(i32* nonnull @gi, i32 %i) +// CHECK: call void asm "st $1, $0", "=*T,r"(i32* nonnull elementtype(i32) @gi, i32 %i) } int test_load_m() { @@ -38,7 +38,7 @@ asm("l %0, %1" : "=r" (i) : "m" (gi)); return i; // CHECK-LABEL: define{{.*}} signext i32 @test_load_m() -// CHECK: call i32 asm "l $0, $1", "=r,*m"(i32* nonnull @gi) +// CHECK: call i32 asm "l $0, $1", "=r,*m"(i32* nonnull elementtype(i32) @gi) } int test_load_Q() { @@ -46,7 +46,7 @@ asm("l %0, %1" : "=r" (i) : "Q" (gi)); return i; // CHECK-LABEL: define{{.*}} signext i32 @test_load_Q() -// CHECK: call i32 asm "l $0, $1", "=r,*Q"(i32* nonnull @gi) +// CHECK: call i32 asm "l $0, $1", "=r,*Q"(i32* nonnull elementtype(i32) @gi) } int test_load_R() { @@ -54,7 +54,7 @@ asm("l %0, %1" : "=r" (i) : "R" (gi)); return i; // CHECK-LABEL: define{{.*}} signext i32 @test_load_R() -// CHECK: call i32 asm "l $0, $1", "=r,*R"(i32* nonnull @gi) +// CHECK: call i32 asm "l $0, $1", "=r,*R"(i32* nonnull elementtype(i32) @gi) } int test_load_S() { @@ -62,7 +62,7 @@ asm("l %0, %1" : "=r" (i) : "S" (gi)); return i; // CHECK-LABEL: define{{.*}} signext i32 @test_load_S() -// CHECK: call i32 asm "l $0, $1", "=r,*S"(i32* nonnull @gi) +// CHECK: call i32 asm "l $0, $1", "=r,*S"(i32* nonnull elementtype(i32) @gi) } int test_load_T() { @@ -70,13 +70,13 @@ asm("l %0, %1" : "=r" (i) : "T" (gi)); return i; // CHECK-LABEL: define{{.*}} signext i32 @test_load_T() -// CHECK: call i32 asm "l $0, $1", "=r,*T"(i32* nonnull @gi) +// CHECK: call i32 asm "l $0, $1", "=r,*T"(i32* nonnull elementtype(i32) @gi) } void test_mI(unsigned char *c) { asm volatile("cli %0, %1" :: "Q" (*c), "I" (100)); // CHECK-LABEL: define{{.*}} void @test_mI(i8* %c) -// CHECK: call void asm sideeffect "cli $0, $1", "*Q,I"(i8* %c, i32 100) +// CHECK: call void asm sideeffect "cli $0, $1", "*Q,I"(i8* elementtype(i8) %c, i32 100) } unsigned int test_dJa(unsigned int i, unsigned int j) { Index: clang/test/CodeGen/aarch64-inline-asm.c =================================================================== --- clang/test/CodeGen/aarch64-inline-asm.c +++ clang/test/CodeGen/aarch64-inline-asm.c @@ -17,7 +17,7 @@ asm("ldr %0, %1" : "=r"(var32) : "m"(var)); asm("ldr %0, [%1]" : "=r"(var64) : "r"(&var)); -// CHECK: call i32 asm "ldr $0, $1", "=r,*m"(i64* @var) +// CHECK: call i32 asm "ldr $0, $1", "=r,*m"(i64* elementtype(i64) @var) // CHECK: call i64 asm "ldr $0, [$1]", "=r,r"(i64* @var) } @@ -52,7 +52,7 @@ void test_constraint_Q(void) { int val; asm("ldxr %0, %1" : "=r"(val) : "Q"(var)); -// CHECK: call i32 asm "ldxr $0, $1", "=r,*Q"(i64* @var) +// CHECK: call i32 asm "ldxr $0, $1", "=r,*Q"(i64* elementtype(i64) @var) } void test_gcc_registers(void) { Index: clang/test/CodeGen/asm-inout.c =================================================================== --- clang/test/CodeGen/asm-inout.c +++ clang/test/CodeGen/asm-inout.c @@ -5,7 +5,7 @@ // CHECK: @test1 void test1() { // CHECK: [[REGCALLRESULT:%[a-zA-Z0-9\.]+]] = call i32* @foo() - // CHECK: call void asm "foobar", "=*m,*m,~{dirflag},~{fpsr},~{flags}"(i32* [[REGCALLRESULT]], i32* [[REGCALLRESULT]]) + // CHECK: call void asm "foobar", "=*m,*m,~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) [[REGCALLRESULT]], i32* elementtype(i32) [[REGCALLRESULT]]) asm ("foobar" : "+m"(*foo())); } Index: clang/test/CodeGen/asm.c =================================================================== --- clang/test/CodeGen/asm.c +++ clang/test/CodeGen/asm.c @@ -246,7 +246,7 @@ : : "m"(t29_var)); // CHECK: @t29 - // CHECK: call void asm sideeffect "movl %eax, $0", "*m,~{dirflag},~{fpsr},~{flags}"([1 x i32]* @t29_var) + // CHECK: call void asm sideeffect "movl %eax, $0", "*m,~{dirflag},~{fpsr},~{flags}"([1 x i32]* elementtype([1 x i32]) @t29_var) } void t30(int len) { Index: clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond-64bit-only.c =================================================================== --- clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond-64bit-only.c +++ clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond-64bit-only.c @@ -10,7 +10,7 @@ long test_ldarx(volatile long* a) { // CHECK64-LABEL: @test_ldarx - // CHECK64: %0 = tail call i64 asm sideeffect "ldarx $0, ${1:y}", "=r,*Z,~{memory}"(i64* %a) + // CHECK64: %0 = tail call i64 asm sideeffect "ldarx $0, ${1:y}", "=r,*Z,~{memory}"(i64* elementtype(i64) %a) // CHECK32-ERROR: error: this builtin is only available on 64-bit targets return __ldarx(a); } Index: clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond.c =================================================================== --- clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond.c +++ clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond.c @@ -13,20 +13,20 @@ int test_lwarx(volatile int* a) { // CHECK-LABEL: @test_lwarx - // CHECK: %0 = tail call i32 asm sideeffect "lwarx $0, ${1:y}", "=r,*Z,~{memory}"(i32* %a) + // CHECK: %0 = tail call i32 asm sideeffect "lwarx $0, ${1:y}", "=r,*Z,~{memory}"(i32* elementtype(i32) %a) return __lwarx(a); } short test_lharx(volatile short *a) { // CHECK-LABEL: @test_lharx - // CHECK: %0 = tail call i16 asm sideeffect "lharx $0, ${1:y}", "=r,*Z,~{memory}"(i16* %a) + // CHECK: %0 = tail call i16 asm sideeffect "lharx $0, ${1:y}", "=r,*Z,~{memory}"(i16* elementtype(i16) %a) // CHECK-NON-PWR8-ERR: error: this builtin is only valid on POWER8 or later CPUs return __lharx(a); } char test_lbarx(volatile char *a) { // CHECK-LABEL: @test_lbarx - // CHECK: %0 = tail call i8 asm sideeffect "lbarx $0, ${1:y}", "=r,*Z,~{memory}"(i8* %a) + // CHECK: %0 = tail call i8 asm sideeffect "lbarx $0, ${1:y}", "=r,*Z,~{memory}"(i8* elementtype(i8) %a) // CHECK-NON-PWR8-ERR: error: this builtin is only valid on POWER8 or later CPUs return __lbarx(a); } @@ -50,14 +50,14 @@ // Extra test cases that previously caused error during usage. int test_lharx_intret(volatile short *a) { // CHECK-LABEL: @test_lharx_intret - // CHECK: %0 = tail call i16 asm sideeffect "lharx $0, ${1:y}", "=r,*Z,~{memory}"(i16* %a) + // CHECK: %0 = tail call i16 asm sideeffect "lharx $0, ${1:y}", "=r,*Z,~{memory}"(i16* elementtype(i16) %a) // CHECK-NON-PWR8-ERR: error: this builtin is only valid on POWER8 or later CPUs return __lharx(a); } int test_lbarx_intret(volatile char *a) { // CHECK-LABEL: @test_lbarx_intret - // CHECK: %0 = tail call i8 asm sideeffect "lbarx $0, ${1:y}", "=r,*Z,~{memory}"(i8* %a) + // CHECK: %0 = tail call i8 asm sideeffect "lbarx $0, ${1:y}", "=r,*Z,~{memory}"(i8* elementtype(i8) %a) // CHECK-NON-PWR8-ERR: error: this builtin is only valid on POWER8 or later CPUs return __lbarx(a); } Index: clang/test/CodeGen/inline-asm-x86-flag-output.c =================================================================== --- clang/test/CodeGen/inline-asm-x86-flag-output.c +++ clang/test/CodeGen/inline-asm-x86-flag-output.c @@ -2,7 +2,7 @@ int test_cca(long nr, volatile long *addr) { //CHECK-LABEL: @test_cca - //CHECK: = tail call i32 asm "cmp $2,$1", "={@cca},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@cca},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@cca"(x), "=m"(*(volatile long *)(addr)) @@ -15,7 +15,7 @@ int test_ccae(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccae - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccae},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccae},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccae"(x), "=m"(*(volatile long *)(addr)) @@ -28,7 +28,7 @@ int test_ccb(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccb - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccb},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccb},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccb"(x), "=m"(*(volatile long *)(addr)) @@ -41,7 +41,7 @@ int test_ccbe(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccbe - //CHECK: tail call i32 asm "cmp $2,$1", "={@ccbe},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: tail call i32 asm "cmp $2,$1", "={@ccbe},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccbe"(x), "=m"(*(volatile long *)(addr)) @@ -54,7 +54,7 @@ int test_ccc(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccc - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccc},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccc},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccc"(x), "=m"(*(volatile long *)(addr)) @@ -67,7 +67,7 @@ int test_cce(long nr, volatile long *addr) { //CHECK-LABEL: @test_cce - //CHECK: = tail call i32 asm "cmp $2,$1", "={@cce},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@cce},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@cce"(x), "=m"(*(volatile long *)(addr)) @@ -80,7 +80,7 @@ int test_ccz(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccz - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccz},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccz},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccz"(x), "=m"(*(volatile long *)(addr)) @@ -93,7 +93,7 @@ int test_ccg(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccg - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccg},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccg},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccg"(x), "=m"(*(volatile long *)(addr)) @@ -106,7 +106,7 @@ int test_ccge(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccge - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccge},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccge},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccge"(x), "=m"(*(volatile long *)(addr)) @@ -119,7 +119,7 @@ int test_ccl(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccl - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccl},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccl},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccl"(x), "=m"(*(volatile long *)(addr)) @@ -132,7 +132,7 @@ int test_ccle(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccle - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccle},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccle},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccle"(x), "=m"(*(volatile long *)(addr)) @@ -145,7 +145,7 @@ int test_ccna(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccna - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccna},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccna},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccna"(x), "=m"(*(volatile long *)(addr)) @@ -158,7 +158,7 @@ int test_ccnae(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccnae - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnae},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnae},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccnae"(x), "=m"(*(volatile long *)(addr)) @@ -171,7 +171,7 @@ int test_ccnb(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccnb - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnb},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnb},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccnb"(x), "=m"(*(volatile long *)(addr)) @@ -184,7 +184,7 @@ int test_ccnbe(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccnbe - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnbe},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnbe},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccnbe"(x), "=m"(*(volatile long *)(addr)) @@ -197,7 +197,7 @@ int test_ccnc(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccnc - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnc},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnc},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccnc"(x), "=m"(*(volatile long *)(addr)) @@ -210,7 +210,7 @@ int test_ccne(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccne - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccne},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccne},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccne"(x), "=m"(*(volatile long *)(addr)) @@ -223,7 +223,7 @@ int test_ccnz(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccnz - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnz},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnz},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccnz"(x), "=m"(*(volatile long *)(addr)) @@ -236,7 +236,7 @@ int test_ccng(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccng - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccng},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccng},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccng"(x), "=m"(*(volatile long *)(addr)) @@ -249,7 +249,7 @@ int test_ccnge(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccnge - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnge},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnge},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccnge"(x), "=m"(*(volatile long *)(addr)) @@ -262,7 +262,7 @@ int test_ccnl(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccnl - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnl},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnl},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccnl"(x), "=m"(*(volatile long *)(addr)) @@ -275,7 +275,7 @@ int test_ccnle(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccnle - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnle},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnle},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccnle"(x), "=m"(*(volatile long *)(addr)) @@ -288,7 +288,7 @@ int test_ccno(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccno - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccno},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccno},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccno"(x), "=m"(*(volatile long *)(addr)) @@ -301,7 +301,7 @@ int test_ccnp(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccnp - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnp},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnp},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccnp"(x), "=m"(*(volatile long *)(addr)) @@ -314,7 +314,7 @@ int test_ccns(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccns - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccns},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccns},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccns"(x), "=m"(*(volatile long *)(addr)) @@ -327,7 +327,7 @@ int test_cco(long nr, volatile long *addr) { //CHECK-LABEL: @test_cco - //CHECK: = tail call i32 asm "cmp $2,$1", "={@cco},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@cco},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@cco"(x), "=m"(*(volatile long *)(addr)) @@ -340,7 +340,7 @@ int test_ccp(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccp - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccp},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccp},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccp"(x), "=m"(*(volatile long *)(addr)) @@ -353,7 +353,7 @@ int test_ccs(long nr, volatile long *addr) { //CHECK-LABEL: @test_ccs - //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccs},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) + //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccs},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr) int x; asm("cmp %2,%1" : "=@ccs"(x), "=m"(*(volatile long *)(addr)) Index: clang/test/CodeGen/matrix-type.c =================================================================== --- clang/test/CodeGen/matrix-type.c +++ clang/test/CodeGen/matrix-type.c @@ -169,7 +169,7 @@ // CHECK-NEXT: [[PTR1:%.+]] = bitcast [16 x double]* [[ALLOCA]] to <16 x double>* // CHECK-NEXT: [[PTR2:%.+]] = bitcast [16 x double]* [[ALLOCA]] to <16 x double>* // CHECK-NEXT: [[VAL:%.+]] = load <16 x double>, <16 x double>* [[PTR2]], align 8 - // CHECK-NEXT: call void asm sideeffect "", "=*r|m,0,~{memory},~{dirflag},~{fpsr},~{flags}"(<16 x double>* [[PTR1]], <16 x double> [[VAL]]) + // CHECK-NEXT: call void asm sideeffect "", "=*r|m,0,~{memory},~{dirflag},~{fpsr},~{flags}"(<16 x double>* elementtype(<16 x double>) [[PTR1]], <16 x double> [[VAL]]) // CHECK-NEXT: ret void dx4x4_t m; Index: clang/test/CodeGen/mips-constraints-mem.c =================================================================== --- clang/test/CodeGen/mips-constraints-mem.c +++ clang/test/CodeGen/mips-constraints-mem.c @@ -9,7 +9,7 @@ // 'R': An address that can be used in a non-macro load or stor' // This test will result in the higher and lower nibbles being // switched due to the lwl/lwr instruction pairs. - // CHECK: %{{[0-9]+}} = call i32 asm sideeffect "lwl $0, 1 + $1\0A\09lwr $0, 2 + $1\0A\09", "=r,*R,~{$1}"(i32* %{{[0-9,a-f]+}}) #1, + // CHECK: %{{[0-9]+}} = call i32 asm sideeffect "lwl $0, 1 + $1\0A\09lwr $0, 2 + $1\0A\09", "=r,*R,~{$1}"(i32* elementtype(i32) %{{[0-9,a-f]+}}) #1, int c = 0xffbbccdd; Index: clang/test/CodeGen/mips-inline-asm-modifiers.c =================================================================== --- clang/test/CodeGen/mips-inline-asm-modifiers.c +++ clang/test/CodeGen/mips-inline-asm-modifiers.c @@ -7,8 +7,8 @@ typedef int v4i32 __attribute__((vector_size(16))); - // CHECK: %{{[0-9]+}} = call i32 asm ".set noreorder;\0Alw $0,$1;\0A.set reorder;\0A", "=r,*m,~{$1}"(i32* getelementptr inbounds ([8 x i32], [8 x i32]* @b, i32 {{[0-9]+}}, i32 {{[0-9]+}})) #2, - // CHECK: %{{[0-9]+}} = call i32 asm "lw $0,${1:D};\0A", "=r,*m,~{$1}"(i32* getelementptr inbounds ([8 x i32], [8 x i32]* @b, i32 {{[0-9]+}}, i32 {{[0-9]+}})) #2, + // CHECK: %{{[0-9]+}} = call i32 asm ".set noreorder;\0Alw $0,$1;\0A.set reorder;\0A", "=r,*m,~{$1}"(i32* elementtype(i32) getelementptr inbounds ([8 x i32], [8 x i32]* @b, i32 {{[0-9]+}}, i32 {{[0-9]+}})) #2, + // CHECK: %{{[0-9]+}} = call i32 asm "lw $0,${1:D};\0A", "=r,*m,~{$1}"(i32* elementtype(i32) getelementptr inbounds ([8 x i32], [8 x i32]* @b, i32 {{[0-9]+}}, i32 {{[0-9]+}})) #2, // CHECK: %{{[0-9]+}} = call <4 x i32> asm "ldi.w ${0:w},1", "=f,~{$1}" int b[8] = {0,1,2,3,4,5,6,7}; int main() Index: clang/test/CodeGen/mips-inline-asm.c =================================================================== --- clang/test/CodeGen/mips-inline-asm.c +++ clang/test/CodeGen/mips-inline-asm.c @@ -5,17 +5,17 @@ void m () { asm("lw $1, %0" :: "m"(data)); - // CHECK: call void asm sideeffect "lw $$1, $0", "*m,~{$1}"(i32* @data) + // CHECK: call void asm sideeffect "lw $$1, $0", "*m,~{$1}"(i32* elementtype(i32) @data) } void ZC () { asm("ll $1, %0" :: "ZC"(data)); - // CHECK: call void asm sideeffect "ll $$1, $0", "*^ZC,~{$1}"(i32* @data) + // CHECK: call void asm sideeffect "ll $$1, $0", "*^ZC,~{$1}"(i32* elementtype(i32) @data) } void R () { asm("lw $1, %0" :: "R"(data)); - // CHECK: call void asm sideeffect "lw $$1, $0", "*R,~{$1}"(i32* @data) + // CHECK: call void asm sideeffect "lw $$1, $0", "*R,~{$1}"(i32* elementtype(i32) @data) } int additionalClobberedRegisters () { Index: clang/test/CodeGen/mozilla-ms-inline-asm.c =================================================================== --- clang/test/CodeGen/mozilla-ms-inline-asm.c +++ clang/test/CodeGen/mozilla-ms-inline-asm.c @@ -38,7 +38,7 @@ // CHECK-SAME: pop ebp // CHECK-SAME: ret // CHECK: "=*m,*m,*m,*m,*m,~{eax},~{ebp},~{ecx},~{edx},~{flags},~{esp},~{dirflag},~{fpsr},~{flags}" -// CHECK: (i8** %8, i32* %7, void (...)* bitcast (void ()* @invoke_copy_to_stack to void (...)*), i8** %5, i32* %6) +// CHECK: (i8** elementtype(i8*) %8, i32* elementtype(i32) %7, void (...)* elementtype(void (...)) bitcast (void ()* @invoke_copy_to_stack to void (...)*), i8** elementtype(i8*) %5, i32* elementtype(i32) %6) // CHECK: ret void __asm { mov edx,paramCount Index: clang/test/CodeGen/ms-inline-asm-64.c =================================================================== --- clang/test/CodeGen/ms-inline-asm-64.c +++ clang/test/CodeGen/ms-inline-asm-64.c @@ -36,7 +36,7 @@ // CHECK-SAME: lea ebx, $0 // CHECK-SAME: mov eax, [ebx] // CHECK-SAME: mov [ebx + $$4], ecx -// CHECK-SAME: "*m,~{eax},~{ebx},~{dirflag},~{fpsr},~{flags}"(%struct.t3_type* %{{.*}}) +// CHECK-SAME: "*m,~{eax},~{ebx},~{dirflag},~{fpsr},~{flags}"(%struct.t3_type* elementtype(%struct.t3_type) %{{.*}}) } int t4() { @@ -56,7 +56,7 @@ // CHECK-SAME: lea ebx, $0 // CHECK-SAME: mov eax, [ebx] // CHECK-SAME: mov [ebx + $$4], ecx -// CHECK-SAME: "*m,~{eax},~{ebx},~{dirflag},~{fpsr},~{flags}"(%struct.t3_type* %{{.*}}) +// CHECK-SAME: "*m,~{eax},~{ebx},~{dirflag},~{fpsr},~{flags}"(%struct.t3_type* elementtype(%struct.t3_type) %{{.*}}) } void bar() {} @@ -70,5 +70,5 @@ // CHECK: call void asm sideeffect inteldialect // CHECK-SAME: call qword ptr ${0:P} // CHECK-SAME: jmp qword ptr ${1:P} - // CHECK-SAME: "*m,*m,~{dirflag},~{fpsr},~{flags}"(void (...)* bitcast (void ()* @bar to void (...)*), void (...)* bitcast (void ()* @bar to void (...)*)) + // CHECK-SAME: "*m,*m,~{dirflag},~{fpsr},~{flags}"(void (...)* elementtype(void (...)) bitcast (void ()* @bar to void (...)*), void (...)* elementtype(void (...)) bitcast (void ()* @bar to void (...)*)) } Index: clang/test/CodeGen/ms-inline-asm-static-variable.c =================================================================== --- clang/test/CodeGen/ms-inline-asm-static-variable.c +++ clang/test/CodeGen/ms-inline-asm-static-variable.c @@ -5,6 +5,6 @@ static int arr[10]; void t1() { // CHECK: @arr = internal global [10 x i32] - // CHECK: call void asm sideeffect inteldialect "mov dword ptr arr[edx * $$4],edx", "=*m,{{.*}}([10 x i32]* @arr) + // CHECK: call void asm sideeffect inteldialect "mov dword ptr arr[edx * $$4],edx", "=*m,{{.*}}([10 x i32]* elementtype([10 x i32]) @arr) __asm mov dword ptr arr[edx*4],edx } Index: clang/test/CodeGen/ms-inline-asm.c =================================================================== --- clang/test/CodeGen/ms-inline-asm.c +++ clang/test/CodeGen/ms-inline-asm.c @@ -114,7 +114,7 @@ // CHECK: call i32 asm sideeffect inteldialect // CHECK-SAME: mov eax, $2 // CHECK-SAME: mov $0, eax -// CHECK-SAME: "=*m,=&{eax},*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}) +// CHECK-SAME: "=*m,=&{eax},*m,~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}, i32* elementtype(i32) %{{.*}}) // CHECK: [[RET:%[a-zA-Z0-9]+]] = load i32, i32* [[J]], align 4 // CHECK: ret i32 [[RET]] } @@ -140,7 +140,7 @@ // CHECK-SAME: mov $0, eax // CHECK-SAME: mov eax, $4 // CHECK-SAME: mov $1, eax -// CHECK-SAME: "=*m,=*m,=&{eax},*m,*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}) +// CHECK-SAME: "=*m,=*m,=&{eax},*m,*m,~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}, i32* elementtype(i32) %{{.*}}, i32* elementtype(i32) %{{.*}}, i32* elementtype(i32) %{{.*}}) } void t13() { @@ -152,7 +152,7 @@ // CHECK: call void asm sideeffect inteldialect // CHECK-SAME: movzx eax, byte ptr $0 // CHECK-SAME: movzx eax, word ptr $1 -// CHECK-SAME: "*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i8* %{{.*}}i, i16* %{{.*}}j) +// CHECK-SAME: "*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i8* elementtype(i8) %{{.*}}i, i16* elementtype(i16) %{{.*}}j) } void t13_brac() { @@ -164,7 +164,7 @@ // CHECK: call void asm sideeffect inteldialect // CHECK-SAME: movzx eax, byte ptr $0 // CHECK-SAME: movzx eax, word ptr $1 -// CHECK-SAME: "*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i8* %{{.*}}i, i16* %{{.*}}j) +// CHECK-SAME: "*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i8* elementtype(i8) %{{.*}}i, i16* elementtype(i16) %{{.*}}j) } void t14() { @@ -177,7 +177,7 @@ .endif } // CHECK: t14 -// CHECK: call void asm sideeffect inteldialect ".if 1\0A\09mov eax, $0\0A\09.else\0A\09mov ebx, j\0A\09.endif", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect ".if 1\0A\09mov eax, $0\0A\09.else\0A\09mov ebx, j\0A\09.endif", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) } int gvar = 10; @@ -196,7 +196,7 @@ // CHECK: mov eax, $4 + $$1 __asm mov eax, 1+offset gvar+1 ; eax = 2 + address of gvar // CHECK: mov eax, $5 + $$2 -// CHECK: "*m,r,i,i,i,i,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* @{{.*}}, i32* @{{.*}}, i32* @{{.*}}, i32* @{{.*}}) +// CHECK: "*m,r,i,i,i,i,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}, i32* %{{.*}}, i32* @{{.*}}, i32* @{{.*}}, i32* @{{.*}}, i32* @{{.*}}) } void t16() { @@ -312,7 +312,7 @@ void t24() { __asm call t24_helper // CHECK: t24 -// CHECK: call void asm sideeffect inteldialect "call dword ptr ${0:P}", "*m,~{dirflag},~{fpsr},~{flags}"(void ()* @t24_helper) +// CHECK: call void asm sideeffect inteldialect "call dword ptr ${0:P}", "*m,~{dirflag},~{fpsr},~{flags}"(void ()* elementtype(void ()) @t24_helper) } void t25() { @@ -376,7 +376,7 @@ // CHECK: mov dword ptr $1, $$8 __asm mov otype, TYPE arr // CHECK: mov dword ptr $2, $$4 -// CHECK: "=*m,=*m,=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}) +// CHECK: "=*m,=*m,=*m,~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}, i32* elementtype(i32) %{{.*}}, i32* elementtype(i32) %{{.*}}) } int results[2] = {13, 37}; @@ -389,7 +389,7 @@ __asm mov res, edi // CHECK: mov $0, edi return res; -// CHECK: "=*m,={eax},*m,~{edi},~{dirflag},~{fpsr},~{flags}"(i32** %{{.*}}, [2 x i32]* @{{.*}}) +// CHECK: "=*m,={eax},*m,~{edi},~{dirflag},~{fpsr},~{flags}"(i32** elementtype(i32*) %{{.*}}, [2 x i32]* elementtype([2 x i32]) @{{.*}}) } void t31() { @@ -412,7 +412,7 @@ // CHECK: mov ax, word ptr $2 __asm mov al, byte ptr i // CHECK: mov al, byte ptr $3 -// CHECK: "*m,*m,*m,*m,~{al},~{ax},~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}) +// CHECK: "*m,*m,*m,*m,~{al},~{ax},~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}, i32* elementtype(i32) %{{.*}}, i32* elementtype(i32) %{{.*}}, i32* elementtype(i32) %{{.*}}) } void t33() { @@ -426,7 +426,7 @@ // CHECK: mov ax, word ptr $2 __asm mov al, byte ptr [i] // CHECK: mov al, byte ptr $3 -// CHECK: "*m,*m,*m,*m,~{al},~{ax},~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}) +// CHECK: "*m,*m,*m,*m,~{al},~{ax},~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}, i32* elementtype(i32) %{{.*}}, i32* elementtype(i32) %{{.*}}, i32* elementtype(i32) %{{.*}}) } void t34() { @@ -452,31 +452,31 @@ int arr[4]; // Work around PR20368: These should be single line blocks __asm { mov eax, 4[arr] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) __asm { mov eax, 4[arr + 4] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) __asm { mov eax, 8[arr + 4 + 32*2 - 4] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$72]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$72]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) __asm { mov eax, 12[4 + arr] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$16]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$16]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) __asm { mov eax, 4[4 + arr + 4] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$12]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$12]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) __asm { mov eax, 4[64 + arr + (2*32)] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$132]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$132]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) __asm { mov eax, 4[64 + arr - 2*32] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) __asm { mov eax, [arr + 4] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) __asm { mov eax, [arr + 4 + 32*2 - 4] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$64]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$64]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) __asm { mov eax, [4 + arr] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) __asm { mov eax, [4 + arr + 4] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) __asm { mov eax, [64 + arr + (2*32)] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$128]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$128]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) __asm { mov eax, [64 + arr - 2*32] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) } void t37() { @@ -507,21 +507,21 @@ int arr[4]; // Work around PR20368: These should be single line blocks __asm { mov eax, 4+4[arr] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) __asm { mov eax, (4+4)[arr + 4] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$12]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$12]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) __asm { mov eax, 8*2[arr + 4 + 32*2 - 4] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$80]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$80]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) __asm { mov eax, 12+20[4 + arr] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$36]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$36]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) __asm { mov eax, 4*16+4[4 + arr + 4] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$76]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$76]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) __asm { mov eax, 4*4[64 + arr + (2*32)] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$144]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$144]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) __asm { mov eax, 4*(4-2)[64 + arr - 2*32] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) __asm { mov eax, 32*(4-2)[arr - 2*32] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) } void cpuid() { @@ -577,7 +577,7 @@ // CHECK: fld dword ptr $1 __asm fistp i // CHECK: fistp dword ptr $0 -// CHECK: "=*m,*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, float* %{{.*}}) +// CHECK: "=*m,*m,~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}, float* elementtype(float) %{{.*}}) } void t41(unsigned short a) { @@ -602,7 +602,7 @@ int flags; __asm mov flags, eax // CHECK: mov $0, eax -// CHECK: "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %flags) +// CHECK: "=*m,~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %flags) } void t42b() { @@ -610,7 +610,7 @@ int mxcsr; __asm mov mxcsr, eax // CHECK: mov $0, eax -// CHECK: "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %mxcsr) +// CHECK: "=*m,~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %mxcsr) } void t43() { @@ -618,31 +618,31 @@ C strct; // Work around PR20368: These should be single line blocks __asm { mov eax, 4[strct.c1] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) __asm { mov eax, 4[strct.c3 + 4] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) __asm { mov eax, 8[strct.c2.a + 4 + 32*2 - 4] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$72]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$72]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) __asm { mov eax, 12[4 + strct.c2.b] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$16]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$16]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) __asm { mov eax, 4[4 + strct.c4.b2.b + 4] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$12]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$12]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) __asm { mov eax, 4[64 + strct.c1 + (2*32)] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$132]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$132]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) __asm { mov eax, 4[64 + strct.c2.a - 2*32] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) __asm { mov eax, [strct.c4.b1 + 4] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) __asm { mov eax, [strct.c4.b2.a + 4 + 32*2 - 4] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$64]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$64]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) __asm { mov eax, [4 + strct.c1] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) __asm { mov eax, [4 + strct.c2.b + 4] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) __asm { mov eax, [64 + strct.c3 + (2*32)] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$128]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$128]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) __asm { mov eax, [64 + strct.c4.b2.b - 2*32] } -// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) } void t44() { @@ -684,7 +684,7 @@ void call_clobber() { __asm call t41 // CHECK-LABEL: define{{.*}} void @call_clobber - // CHECK: call void asm sideeffect inteldialect "call dword ptr ${0:P}", "*m,~{dirflag},~{fpsr},~{flags}"(void (i16)* @t41) + // CHECK: call void asm sideeffect inteldialect "call dword ptr ${0:P}", "*m,~{dirflag},~{fpsr},~{flags}"(void (i16)* elementtype(void (i16)) @t41) } void xgetbv() { Index: clang/test/CodeGen/ms-inline-asm.cpp =================================================================== --- clang/test/CodeGen/ms-inline-asm.cpp +++ clang/test/CodeGen/ms-inline-asm.cpp @@ -23,7 +23,7 @@ // CHECK-SAME: mov eax, $2 // CHECK-SAME: mov eax, dword ptr $3 // CHECK-SAME: mov eax, dword ptr $4 -// CHECK-SAME: "*m,*m,*m,*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3Bar3ptrE, i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3ptrE) +// CHECK-SAME: "*m,*m,*m,*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** elementtype(i32*) @_ZN3Foo3ptrE, i32** elementtype(i32*) @_ZN3Foo3Bar3ptrE, i32** elementtype(i32*) @_ZN3Foo3ptrE, i32** elementtype(i32*) @_ZN3Foo3ptrE, i32** elementtype(i32*) @_ZN3Foo3ptrE) __asm mov eax, Foo ::ptr __asm mov eax, Foo :: Bar :: ptr __asm mov eax, [Foo:: ptr] @@ -92,7 +92,7 @@ // CHECK: call void asm sideeffect inteldialect // CHECK-SAME: mov eax, $1 // CHECK-SAME: mov $0, eax -// CHECK-SAME: "=*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* @_ZN2T41yE, i32* {{.*}}) +// CHECK-SAME: "=*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) @_ZN2T41yE, i32* elementtype(i32) {{.*}}) } template struct T5 { @@ -111,7 +111,7 @@ // CHECK-SAME: push $0 // CHECK-SAME: call dword ptr ${2:P} // CHECK-SAME: mov $1, eax - // CHECK-SAME: "=*m,=*m,*m,~{esp},~{dirflag},~{fpsr},~{flags}"(i32* %y, i32* %x, i32 (float)* @_ZN2T5IiE6createIfEEiT_) + // CHECK-SAME: "=*m,=*m,*m,~{esp},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %y, i32* elementtype(i32) %x, i32 (float)* elementtype(i32 (float)) @_ZN2T5IiE6createIfEEiT_) } // Just verify this doesn't emit an error. Index: clang/test/CodeGen/ms-intrinsics.c =================================================================== --- clang/test/CodeGen/ms-intrinsics.c +++ clang/test/CodeGen/ms-intrinsics.c @@ -626,48 +626,48 @@ #if defined(__i386__) || defined(__x86_64__) long test_InterlockedExchange_HLEAcquire(long volatile *Target, long Value) { // CHECK-INTEL: define{{.*}} i32 @test_InterlockedExchange_HLEAcquire(i32*{{[a-z_ ]*}}%Target, i32{{[a-z_ ]*}}%Value) -// CHECK-INTEL: call i32 asm sideeffect ".byte 0xf2 ; lock ; xchg $($0, $1$|$1, $0$)", "=r,=*m,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %Target, i32 %Value, i32* %Target) +// CHECK-INTEL: call i32 asm sideeffect ".byte 0xf2 ; lock ; xchg $($0, $1$|$1, $0$)", "=r,=*m,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %Target, i32 %Value, i32* elementtype(i32) %Target) return _InterlockedExchange_HLEAcquire(Target, Value); } long test_InterlockedExchange_HLERelease(long volatile *Target, long Value) { // CHECK-INTEL: define{{.*}} i32 @test_InterlockedExchange_HLERelease(i32*{{[a-z_ ]*}}%Target, i32{{[a-z_ ]*}}%Value) -// CHECK-INTEL: call i32 asm sideeffect ".byte 0xf3 ; lock ; xchg $($0, $1$|$1, $0$)", "=r,=*m,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %Target, i32 %Value, i32* %Target) +// CHECK-INTEL: call i32 asm sideeffect ".byte 0xf3 ; lock ; xchg $($0, $1$|$1, $0$)", "=r,=*m,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %Target, i32 %Value, i32* elementtype(i32) %Target) return _InterlockedExchange_HLERelease(Target, Value); } long test_InterlockedCompareExchange_HLEAcquire(long volatile *Destination, long Exchange, long Comparand) { // CHECK-INTEL: define{{.*}} i32 @test_InterlockedCompareExchange_HLEAcquire(i32*{{[a-z_ ]*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comparand) -// CHECK-INTEL: call i32 asm sideeffect ".byte 0xf2 ; lock ; cmpxchg $($2, $1$|$1, $2$)", "={ax},=*m,r,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %Destination, i32 %Exchange, i32 %Comparand, i32* %Destination) +// CHECK-INTEL: call i32 asm sideeffect ".byte 0xf2 ; lock ; cmpxchg $($2, $1$|$1, $2$)", "={ax},=*m,r,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %Destination, i32 %Exchange, i32 %Comparand, i32* elementtype(i32) %Destination) return _InterlockedCompareExchange_HLEAcquire(Destination, Exchange, Comparand); } long test_InterlockedCompareExchange_HLERelease(long volatile *Destination, long Exchange, long Comparand) { // CHECK-INTEL: define{{.*}} i32 @test_InterlockedCompareExchange_HLERelease(i32*{{[a-z_ ]*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comparand) -// CHECK-INTEL: call i32 asm sideeffect ".byte 0xf3 ; lock ; cmpxchg $($2, $1$|$1, $2$)", "={ax},=*m,r,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %Destination, i32 %Exchange, i32 %Comparand, i32* %Destination) +// CHECK-INTEL: call i32 asm sideeffect ".byte 0xf3 ; lock ; cmpxchg $($2, $1$|$1, $2$)", "={ax},=*m,r,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %Destination, i32 %Exchange, i32 %Comparand, i32* elementtype(i32) %Destination) return _InterlockedCompareExchange_HLERelease(Destination, Exchange, Comparand); } #endif #if defined(__x86_64__) __int64 test_InterlockedExchange64_HLEAcquire(__int64 volatile *Target, __int64 Value) { // CHECK-X64: define{{.*}} i64 @test_InterlockedExchange64_HLEAcquire(i64*{{[a-z_ ]*}}%Target, i64{{[a-z_ ]*}}%Value) -// CHECK-X64: call i64 asm sideeffect ".byte 0xf2 ; lock ; xchg $($0, $1$|$1, $0$)", "=r,=*m,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %Target, i64 %Value, i64* %Target) +// CHECK-X64: call i64 asm sideeffect ".byte 0xf2 ; lock ; xchg $($0, $1$|$1, $0$)", "=r,=*m,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %Target, i64 %Value, i64* elementtype(i64) %Target) return _InterlockedExchange64_HLEAcquire(Target, Value); } __int64 test_InterlockedExchange64_HLERelease(__int64 volatile *Target, __int64 Value) { // CHECK-X64: define{{.*}} i64 @test_InterlockedExchange64_HLERelease(i64*{{[a-z_ ]*}}%Target, i64{{[a-z_ ]*}}%Value) -// CHECK-X64: call i64 asm sideeffect ".byte 0xf3 ; lock ; xchg $($0, $1$|$1, $0$)", "=r,=*m,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %Target, i64 %Value, i64* %Target) +// CHECK-X64: call i64 asm sideeffect ".byte 0xf3 ; lock ; xchg $($0, $1$|$1, $0$)", "=r,=*m,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %Target, i64 %Value, i64* elementtype(i64) %Target) return _InterlockedExchange64_HLERelease(Target, Value); } __int64 test_InterlockedCompareExchange64_HLEAcquire(__int64 volatile *Destination, __int64 Exchange, __int64 Comparand) { // CHECK-X64: define{{.*}} i64 @test_InterlockedCompareExchange64_HLEAcquire(i64*{{[a-z_ ]*}}%Destination, i64{{[a-z_ ]*}}%Exchange, i64{{[a-z_ ]*}}%Comparand) -// CHECK-X64: call i64 asm sideeffect ".byte 0xf2 ; lock ; cmpxchg $($2, $1$|$1, $2$)", "={ax},=*m,r,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %Destination, i64 %Exchange, i64 %Comparand, i64* %Destination) +// CHECK-X64: call i64 asm sideeffect ".byte 0xf2 ; lock ; cmpxchg $($2, $1$|$1, $2$)", "={ax},=*m,r,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %Destination, i64 %Exchange, i64 %Comparand, i64* elementtype(i64) %Destination) return _InterlockedCompareExchange64_HLEAcquire(Destination, Exchange, Comparand); } __int64 test_InterlockedCompareExchange64_HLERelease(__int64 volatile *Destination, __int64 Exchange, __int64 Comparand) { // CHECK-X64: define{{.*}} i64 @test_InterlockedCompareExchange64_HLERelease(i64*{{[a-z_ ]*}}%Destination, i64{{[a-z_ ]*}}%Exchange, i64{{[a-z_ ]*}}%Comparand) -// CHECK-X64: call i64 asm sideeffect ".byte 0xf3 ; lock ; cmpxchg $($2, $1$|$1, $2$)", "={ax},=*m,r,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %Destination, i64 %Exchange, i64 %Comparand, i64* %Destination) +// CHECK-X64: call i64 asm sideeffect ".byte 0xf3 ; lock ; cmpxchg $($2, $1$|$1, $2$)", "={ax},=*m,r,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %Destination, i64 %Exchange, i64 %Comparand, i64* elementtype(i64) %Destination) return _InterlockedCompareExchange64_HLERelease(Destination, Exchange, Comparand); } #endif Index: clang/test/CodeGen/mult-alt-generic.c =================================================================== --- clang/test/CodeGen/mult-alt-generic.c +++ clang/test/CodeGen/mult-alt-generic.c @@ -17,7 +17,7 @@ // CHECK: @single_m void single_m() { - // CHECK: call void asm "foo $1,$0", "=*m,*m[[CLOBBERS:[a-zA-Z0-9@%{},~_$ ]*\"]](i32* {{[a-zA-Z0-9@%]+}}, i32* {{[a-zA-Z0-9@%]+}}) + // CHECK: call void asm "foo $1,$0", "=*m,*m[[CLOBBERS:[a-zA-Z0-9@%{},~_$ ]*\"]](i32* elementtype(i32) {{[a-zA-Z0-9@%]+}}, i32* elementtype(i32) {{[a-zA-Z0-9@%]+}}) asm("foo %1,%0" : "=m" (mout0) : "m" (min1)); } @@ -150,7 +150,7 @@ // CHECK: @multi_m void multi_m() { - // CHECK: call void asm "foo $1,$0", "=*m|r,m|r[[CLOBBERS]](i32* {{[a-zA-Z0-9@%]+}}, i32 {{[a-zA-Z0-9@%]+}}) + // CHECK: call void asm "foo $1,$0", "=*m|r,m|r[[CLOBBERS]](i32* elementtype(i32) {{[a-zA-Z0-9@%]+}}, i32 {{[a-zA-Z0-9@%]+}}) asm("foo %1,%0" : "=m,r" (mout0) : "m,r" (min1)); } Index: clang/test/CodeGen/mult-alt-x86.c =================================================================== --- clang/test/CodeGen/mult-alt-x86.c +++ clang/test/CodeGen/mult-alt-x86.c @@ -123,144 +123,144 @@ // CHECK: @single_I void single_I() { - // CHECK: asm "foo $1,$0", "=*m,I[[CLOBBERS]](i32* @mout0, i32 1) + // CHECK: asm "foo $1,$0", "=*m,I[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 1) asm("foo %1,%0" : "=m" (mout0) : "I" (1)); } // CHECK: @single_J void single_J() { - // CHECK: asm "foo $1,$0", "=*m,J[[CLOBBERS]](i32* @mout0, i32 1) + // CHECK: asm "foo $1,$0", "=*m,J[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 1) asm("foo %1,%0" : "=m" (mout0) : "J" (1)); } // CHECK: @single_K void single_K() { - // CHECK: asm "foo $1,$0", "=*m,K[[CLOBBERS]](i32* @mout0, i32 1) + // CHECK: asm "foo $1,$0", "=*m,K[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 1) asm("foo %1,%0" : "=m" (mout0) : "K" (1)); } // CHECK: @single_L void single_L() { - // CHECK: asm "foo $1,$0", "=*m,L[[CLOBBERS]](i32* @mout0, i32 255) + // CHECK: asm "foo $1,$0", "=*m,L[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 255) asm("foo %1,%0" : "=m" (mout0) : "L" (0xff)); - // CHECK: asm "foo $1,$0", "=*m,L[[CLOBBERS]](i32* @mout0, i32 65535) + // CHECK: asm "foo $1,$0", "=*m,L[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 65535) asm("foo %1,%0" : "=m" (mout0) : "L" (0xffff)); - // CHECK: asm "foo $1,$0", "=*m,L[[CLOBBERS]](i32* @mout0, i32 -1) + // CHECK: asm "foo $1,$0", "=*m,L[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 -1) asm("foo %1,%0" : "=m" (mout0) : "L" (0xffffffff)); } // CHECK: @single_M void single_M() { - // CHECK: asm "foo $1,$0", "=*m,M[[CLOBBERS]](i32* @mout0, i32 1) + // CHECK: asm "foo $1,$0", "=*m,M[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 1) asm("foo %1,%0" : "=m" (mout0) : "M" (1)); } // CHECK: @single_N void single_N() { - // CHECK: asm "foo $1,$0", "=*m,N[[CLOBBERS]](i32* @mout0, i32 1) + // CHECK: asm "foo $1,$0", "=*m,N[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 1) asm("foo %1,%0" : "=m" (mout0) : "N" (1)); } // CHECK: @single_G void single_G() { - // CHECK: asm "foo $1,$0", "=*m,G[[CLOBBERS]](i32* @mout0, double {{1.[0]+e[+]*[0]+}}) + // CHECK: asm "foo $1,$0", "=*m,G[[CLOBBERS]](i32* elementtype(i32) @mout0, double {{1.[0]+e[+]*[0]+}}) asm("foo %1,%0" : "=m" (mout0) : "G" (1.0)); } // CHECK: @single_C void single_C() { - // CHECK: asm "foo $1,$0", "=*m,C[[CLOBBERS]](i32* @mout0, double {{1.[0]+e[+]*[0]+}}) + // CHECK: asm "foo $1,$0", "=*m,C[[CLOBBERS]](i32* elementtype(i32) @mout0, double {{1.[0]+e[+]*[0]+}}) asm("foo %1,%0" : "=m" (mout0) : "C" (1.0)); } // CHECK: @single_e void single_e() { - // CHECK: asm "foo $1,$0", "=*m,e[[CLOBBERS]](i32* @mout0, i32 1) + // CHECK: asm "foo $1,$0", "=*m,e[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 1) asm("foo %1,%0" : "=m" (mout0) : "e" (1)); } // CHECK: @single_Z void single_Z() { - // CHECK: asm "foo $1,$0", "=*m,Z[[CLOBBERS]](i32* @mout0, i32 1) + // CHECK: asm "foo $1,$0", "=*m,Z[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 1) asm("foo %1,%0" : "=m" (mout0) : "Z" (1)); } // CHECK: @multi_R void multi_R() { - // CHECK: asm "foo $1,$0", "=*r|R|m,r|R|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + // CHECK: asm "foo $1,$0", "=*r|R|m,r|R|m[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 {{[a-zA-Z0-9@%]+}}) asm("foo %1,%0" : "=r,R,m" (mout0) : "r,R,m" (min1)); } // CHECK: @multi_q void multi_q() { - // CHECK: asm "foo $1,$0", "=*r|q|m,r|q|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + // CHECK: asm "foo $1,$0", "=*r|q|m,r|q|m[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 {{[a-zA-Z0-9@%]+}}) asm("foo %1,%0" : "=r,q,m" (mout0) : "r,q,m" (min1)); } // CHECK: @multi_Q void multi_Q() { - // CHECK: asm "foo $1,$0", "=*r|Q|m,r|Q|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + // CHECK: asm "foo $1,$0", "=*r|Q|m,r|Q|m[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 {{[a-zA-Z0-9@%]+}}) asm("foo %1,%0" : "=r,Q,m" (mout0) : "r,Q,m" (min1)); } // CHECK: @multi_a void multi_a() { - // CHECK: asm "foo $1,$0", "=*r|{ax}|m,r|{ax}|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + // CHECK: asm "foo $1,$0", "=*r|{ax}|m,r|{ax}|m[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 {{[a-zA-Z0-9@%]+}}) asm("foo %1,%0" : "=r,a,m" (mout0) : "r,a,m" (min1)); } // CHECK: @multi_b void multi_b() { - // CHECK: asm "foo $1,$0", "=*r|{bx}|m,r|{bx}|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + // CHECK: asm "foo $1,$0", "=*r|{bx}|m,r|{bx}|m[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 {{[a-zA-Z0-9@%]+}}) asm("foo %1,%0" : "=r,b,m" (mout0) : "r,b,m" (min1)); } // CHECK: @multi_c void multi_c() { - // CHECK: asm "foo $1,$0", "=*r|{cx}|m,r|{cx}|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + // CHECK: asm "foo $1,$0", "=*r|{cx}|m,r|{cx}|m[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 {{[a-zA-Z0-9@%]+}}) asm("foo %1,%0" : "=r,c,m" (mout0) : "r,c,m" (min1)); } // CHECK: @multi_d void multi_d() { - // CHECK: asm "foo $1,$0", "=*r|{dx}|m,r|{dx}|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + // CHECK: asm "foo $1,$0", "=*r|{dx}|m,r|{dx}|m[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 {{[a-zA-Z0-9@%]+}}) asm("foo %1,%0" : "=r,d,m" (mout0) : "r,d,m" (min1)); } // CHECK: @multi_S void multi_S() { - // CHECK: asm "foo $1,$0", "=*r|{si}|m,r|{si}|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + // CHECK: asm "foo $1,$0", "=*r|{si}|m,r|{si}|m[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 {{[a-zA-Z0-9@%]+}}) asm("foo %1,%0" : "=r,S,m" (mout0) : "r,S,m" (min1)); } // CHECK: @multi_D void multi_D() { - // CHECK: asm "foo $1,$0", "=*r|{di}|m,r|{di}|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + // CHECK: asm "foo $1,$0", "=*r|{di}|m,r|{di}|m[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 {{[a-zA-Z0-9@%]+}}) asm("foo %1,%0" : "=r,D,m" (mout0) : "r,D,m" (min1)); } // CHECK: @multi_A void multi_A() { - // CHECK: asm "foo $1,$0", "=*r|A|m,r|A|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + // CHECK: asm "foo $1,$0", "=*r|A|m,r|A|m[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 {{[a-zA-Z0-9@%]+}}) asm("foo %1,%0" : "=r,A,m" (mout0) : "r,A,m" (min1)); } @@ -285,14 +285,14 @@ // CHECK: @multi_y void multi_y() { - // CHECK: asm "foo $1,$0", "=*r|y|m,r|y|m[[CLOBBERS]](double* @dout0, double {{[a-zA-Z0-9@%]+}}) + // CHECK: asm "foo $1,$0", "=*r|y|m,r|y|m[[CLOBBERS]](double* elementtype(double) @dout0, double {{[a-zA-Z0-9@%]+}}) asm("foo %1,%0" : "=r,y,m" (dout0) : "r,y,m" (din1)); } // CHECK: @multi_x void multi_x() { - // CHECK: asm "foo $1,$0", "=*r|x|m,r|x|m[[CLOBBERS]](double* @dout0, double {{[a-zA-Z0-9@%]+}}) + // CHECK: asm "foo $1,$0", "=*r|x|m,r|x|m[[CLOBBERS]](double* elementtype(double) @dout0, double {{[a-zA-Z0-9@%]+}}) asm("foo %1,%0" : "=r,x,m" (dout0) : "r,x,m" (din1)); } @@ -310,69 +310,69 @@ // CHECK: @multi_I void multi_I() { - // CHECK: asm "foo $1,$0", "=*r|m|m,r|I|m[[CLOBBERS]](i32* @mout0, i32 1) + // CHECK: asm "foo $1,$0", "=*r|m|m,r|I|m[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 1) asm("foo %1,%0" : "=r,m,m" (mout0) : "r,I,m" (1)); } // CHECK: @multi_J void multi_J() { - // CHECK: asm "foo $1,$0", "=*r|m|m,r|J|m[[CLOBBERS]](i32* @mout0, i32 1) + // CHECK: asm "foo $1,$0", "=*r|m|m,r|J|m[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 1) asm("foo %1,%0" : "=r,m,m" (mout0) : "r,J,m" (1)); } // CHECK: @multi_K void multi_K() { - // CHECK: asm "foo $1,$0", "=*r|m|m,r|K|m[[CLOBBERS]](i32* @mout0, i32 1) + // CHECK: asm "foo $1,$0", "=*r|m|m,r|K|m[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 1) asm("foo %1,%0" : "=r,m,m" (mout0) : "r,K,m" (1)); } // CHECK: @multi_L void multi_L() { - // CHECK: asm "foo $1,$0", "=*r|m|m,r|L|m[[CLOBBERS]](i32* @mout0, i32 1) + // CHECK: asm "foo $1,$0", "=*r|m|m,r|L|m[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 1) asm("foo %1,%0" : "=r,m,m" (mout0) : "r,L,m" (1)); } // CHECK: @multi_M void multi_M() { - // CHECK: asm "foo $1,$0", "=*r|m|m,r|M|m[[CLOBBERS]](i32* @mout0, i32 1) + // CHECK: asm "foo $1,$0", "=*r|m|m,r|M|m[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 1) asm("foo %1,%0" : "=r,m,m" (mout0) : "r,M,m" (1)); } // CHECK: @multi_N void multi_N() { - // CHECK: asm "foo $1,$0", "=*r|m|m,r|N|m[[CLOBBERS]](i32* @mout0, i32 1) + // CHECK: asm "foo $1,$0", "=*r|m|m,r|N|m[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 1) asm("foo %1,%0" : "=r,m,m" (mout0) : "r,N,m" (1)); } // CHECK: @multi_G void multi_G() { - // CHECK: asm "foo $1,$0", "=*r|m|m,r|G|m[[CLOBBERS]](i32* @mout0, double {{1.[0]+e[+]*[0]+}}) + // CHECK: asm "foo $1,$0", "=*r|m|m,r|G|m[[CLOBBERS]](i32* elementtype(i32) @mout0, double {{1.[0]+e[+]*[0]+}}) asm("foo %1,%0" : "=r,m,m" (mout0) : "r,G,m" (1.0)); } // CHECK: @multi_C void multi_C() { - // CHECK: asm "foo $1,$0", "=*r|m|m,r|C|m[[CLOBBERS]](i32* @mout0, double {{1.[0]+e[+]*[0]+}}) + // CHECK: asm "foo $1,$0", "=*r|m|m,r|C|m[[CLOBBERS]](i32* elementtype(i32) @mout0, double {{1.[0]+e[+]*[0]+}}) asm("foo %1,%0" : "=r,m,m" (mout0) : "r,C,m" (1.0)); } // CHECK: @multi_e void multi_e() { - // CHECK: asm "foo $1,$0", "=*r|m|m,r|e|m[[CLOBBERS]](i32* @mout0, i32 1) + // CHECK: asm "foo $1,$0", "=*r|m|m,r|e|m[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 1) asm("foo %1,%0" : "=r,m,m" (mout0) : "r,e,m" (1)); } // CHECK: @multi_Z void multi_Z() { - // CHECK: asm "foo $1,$0", "=*r|m|m,r|Z|m[[CLOBBERS]](i32* @mout0, i32 1) + // CHECK: asm "foo $1,$0", "=*r|m|m,r|Z|m[[CLOBBERS]](i32* elementtype(i32) @mout0, i32 1) asm("foo %1,%0" : "=r,m,m" (mout0) : "r,Z,m" (1)); } Index: clang/test/CodeGen/ppc64-inline-asm.c =================================================================== --- clang/test/CodeGen/ppc64-inline-asm.c +++ clang/test/CodeGen/ppc64-inline-asm.c @@ -41,12 +41,12 @@ void testZ(void *addr) { asm volatile ("dcbz %y0\n" :: "Z"(*(unsigned char *)addr) : "memory"); // CHECK-LABEL: void @testZ(i8* %addr) -// CHECK: call void asm sideeffect "dcbz ${0:y}\0A", "*Z,~{memory}"(i8* %addr) +// CHECK: call void asm sideeffect "dcbz ${0:y}\0A", "*Z,~{memory}"(i8* elementtype(i8) %addr) } void testZwOff(void *addr, long long off) { asm volatile ("dcbz %y0\n" :: "Z"(*(unsigned char *)(addr + off)) : "memory"); // CHECK-LABEL: void @testZwOff(i8* %addr, i64 %off) // CHECK: %[[VAL:[^ ]+]] = getelementptr i8, i8* %addr, i64 %off -// CHECK: call void asm sideeffect "dcbz ${0:y}\0A", "*Z,~{memory}"(i8* %[[VAL]]) +// CHECK: call void asm sideeffect "dcbz ${0:y}\0A", "*Z,~{memory}"(i8* elementtype(i8) %[[VAL]]) } Index: clang/test/CodeGenCXX/ms-inline-asm-fields.cpp =================================================================== --- clang/test/CodeGenCXX/ms-inline-asm-fields.cpp +++ clang/test/CodeGenCXX/ms-inline-asm-fields.cpp @@ -24,7 +24,7 @@ extern "C" int test_namespace_global() { // CHECK: define{{.*}} i32 @test_namespace_global() -// CHECK: call i32 asm sideeffect inteldialect "mov eax, $1", "{{.*}}"(i32* getelementptr inbounds (%struct.A, %struct.A* @_ZN4asdf8a_globalE, i32 0, i32 2, i32 1)) +// CHECK: call i32 asm sideeffect inteldialect "mov eax, $1", "{{.*}}"(i32* elementtype(i32) getelementptr inbounds (%struct.A, %struct.A* @_ZN4asdf8a_globalE, i32 0, i32 2, i32 1)) // CHECK: ret i32 __asm mov eax, asdf::a_global.a3.b2 } @@ -53,4 +53,4 @@ // CHECK: %[[P:.*]] = alloca %"struct.make_storage_type::type", align 4 // CHECK: %[[B:.*]] = getelementptr inbounds %"struct.make_storage_type::type", %"struct.make_storage_type::type"* %[[P]], i32 0, i32 0 // CHECK: %[[X:.*]] = getelementptr inbounds %"struct.make_storage_type::type::B", %"struct.make_storage_type::type::B"* %[[B]], i32 0, i32 1 -// CHECK: call void asm sideeffect inteldialect "mov edx, dword ptr $0", "*m,~{edx},~{dirflag},~{fpsr},~{flags}"(i32* %[[X]]) +// CHECK: call void asm sideeffect inteldialect "mov edx, dword ptr $0", "*m,~{edx},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %[[X]]) Index: clang/test/CodeGenObjC/exceptions.m =================================================================== --- clang/test/CodeGenObjC/exceptions.m +++ clang/test/CodeGenObjC/exceptions.m @@ -54,14 +54,14 @@ // CHECK-NEXT: br i1 [[CAUGHT]] @try { // Landing pad. Note that we elide the re-enter. - // CHECK: call void asm sideeffect "", "=*m,=*m"(i32* nonnull [[X]] + // CHECK: call void asm sideeffect "", "=*m,=*m"(i32* nonnull elementtype(i32) [[X]] // CHECK-NEXT: call i8* @objc_exception_extract // CHECK-NEXT: [[T1:%.*]] = load i32, i32* [[X]] // CHECK-NEXT: [[T2:%.*]] = add nsw i32 [[T1]], -1 // CHECK: store i32 6, i32* [[X]] x++; - // CHECK-NEXT: call void asm sideeffect "", "*m,*m"(i32* nonnull [[X]] + // CHECK-NEXT: call void asm sideeffect "", "*m,*m"(i32* nonnull elementtype(i32) [[X]] // CHECK-NEXT: call void @foo() // CHECK-NEXT: call void @objc_exception_try_exit // CHECK-NEXT: [[T:%.*]] = load i32, i32* [[X]] Index: clang/test/CodeGenObjC/synchronized.m =================================================================== --- clang/test/CodeGenObjC/synchronized.m +++ clang/test/CodeGenObjC/synchronized.m @@ -32,7 +32,7 @@ // CHECK: call i32 @_setjmp @synchronized(a) { // This is unreachable, but the optimizers can't know that. - // CHECK: call void asm sideeffect "", "=*m,=*m,=*m"(i8** nonnull [[A]], i8** nonnull [[SYNC]] + // CHECK: call void asm sideeffect "", "=*m,=*m,=*m"(i8** nonnull elementtype(i8*) [[A]], i8** nonnull elementtype(i8*) [[SYNC]] // CHECK: call i32 @objc_sync_exit // CHECK: call i8* @objc_exception_extract // CHECK: call void @objc_exception_throw