diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -2548,7 +2548,7 @@ ArgTypes.push_back(BA->getType()); if (!Constraints.empty()) Constraints += ','; - Constraints += 'X'; + Constraints += 'i'; } Fallthrough = createBasicBlock("asm.fallthrough"); } diff --git a/clang/test/CodeGen/asm-goto.c b/clang/test/CodeGen/asm-goto.c --- a/clang/test/CodeGen/asm-goto.c +++ b/clang/test/CodeGen/asm-goto.c @@ -55,14 +55,14 @@ int test4(int out1, int out2) { // CHECK-LABEL: define{{.*}} i32 @test4( - // CHECK: callbr { i32, i32 } asm sideeffect "jne ${3:l}", "={si},={di},r,X,X,0,1 + // CHECK: callbr { i32, i32 } asm sideeffect "jne ${3:l}", "={si},={di},r,i,i,0,1 // CHECK: to label %asm.fallthrough [label %label_true, label %loop] // CHECK-LABEL: asm.fallthrough: if (out1 < out2) asm volatile goto("jne %l3" : "+S"(out1), "+D"(out2) : "r"(out1) :: label_true, loop); else asm volatile goto("jne %l5" : "+S"(out1), "+D"(out2) : "r"(out1), "r"(out2) :: label_true, loop); - // CHECK: callbr { i32, i32 } asm sideeffect "jne ${5:l}", "={si},={di},r,r,X,X,0,1 + // CHECK: callbr { i32, i32 } asm sideeffect "jne ${5:l}", "={si},={di},r,r,i,i,0,1 // CHECK: to label %asm.fallthrough2 [label %label_true, label %loop] // CHECK-LABEL: asm.fallthrough2: return out1 + out2; @@ -74,7 +74,7 @@ int test5(int addr, int size, int limit) { // CHECK-LABEL: define{{.*}} i32 @test5( - // CHECK: callbr i32 asm "add $1,$0 ; jc ${3:l} ; cmp $2,$0 ; ja ${3:l} ; ", "=r,imr,imr,X,0 + // CHECK: callbr i32 asm "add $1,$0 ; jc ${3:l} ; cmp $2,$0 ; ja ${3:l} ; ", "=r,imr,imr,i,0 // CHECK: to label %asm.fallthrough [label %t_err] // CHECK-LABEL: asm.fallthrough: asm goto( @@ -92,7 +92,7 @@ int test6(int out1) { // CHECK-LABEL: define{{.*}} i32 @test6( - // CHECK: callbr i32 asm sideeffect "testl $0, $0; testl $1, $1; jne ${2:l}", "={si},r,X,X,0,{{.*}} i8* blockaddress(@test6, %label_true), i8* blockaddress(@test6, %landing) + // CHECK: callbr i32 asm sideeffect "testl $0, $0; testl $1, $1; jne ${2:l}", "={si},r,i,i,0,{{.*}} i8* blockaddress(@test6, %label_true), i8* blockaddress(@test6, %landing) // CHECK: to label %asm.fallthrough [label %label_true, label %landing] // CHECK-LABEL: asm.fallthrough: // CHECK-LABEL: landing: diff --git a/clang/test/CodeGen/asm.c b/clang/test/CodeGen/asm.c --- a/clang/test/CodeGen/asm.c +++ b/clang/test/CodeGen/asm.c @@ -267,7 +267,7 @@ int t32(int cond) { asm goto("testl %0, %0; jne %l1;" :: "r"(cond)::label_true, loop); - // CHECK: callbr void asm sideeffect "testl $0, $0; jne ${1:l};", "r,X,X,~{dirflag},~{fpsr},~{flags}"(i32 %0, i8* blockaddress(@t32, %label_true), i8* blockaddress(@t32, %loop)) #1 + // CHECK: callbr void asm sideeffect "testl $0, $0; jne ${1:l};", "r,i,i,~{dirflag},~{fpsr},~{flags}"(i32 %0, i8* blockaddress(@t32, %label_true), i8* blockaddress(@t32, %loop)) #1 return 0; loop: return 0; diff --git a/clang/test/Modules/asm-goto.c b/clang/test/Modules/asm-goto.c --- a/clang/test/Modules/asm-goto.c +++ b/clang/test/Modules/asm-goto.c @@ -4,7 +4,7 @@ #include "a.h" // CHECK-LABEL: define {{.*}} @foo( -// CHECK: callbr {{.*}} "=r,X{{.*}} blockaddress(@foo, %indirect)) +// CHECK: callbr {{.*}} "=r,i{{.*}} blockaddress(@foo, %indirect)) // CHECK-NEXT: to label %asm.fallthrough [label %indirect] int bar(void) { diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -8553,7 +8553,6 @@ unsigned ArgNo = 0; // ArgNo - The argument of the CallInst. unsigned ResNo = 0; // ResNo - The result number of the next output. - unsigned NumMatchingOps = 0; for (auto &T : TargetConstraints) { ConstraintOperands.push_back(SDISelAsmOperandInfo(T)); SDISelAsmOperandInfo &OpInfo = ConstraintOperands.back(); @@ -8563,19 +8562,7 @@ (OpInfo.Type == InlineAsm::isOutput && OpInfo.isIndirect)) { OpInfo.CallOperandVal = Call.getArgOperand(ArgNo++); - // Process the call argument. BasicBlocks are labels, currently appearing - // only in asm's. - if (isa(Call) && - ArgNo - 1 >= (cast(&Call)->arg_size() - - cast(&Call)->getNumIndirectDests() - - NumMatchingOps) && - (NumMatchingOps == 0 || - ArgNo - 1 < - (cast(&Call)->arg_size() - NumMatchingOps))) { - const auto *BA = cast(OpInfo.CallOperandVal); - EVT VT = TLI.getValueType(DAG.getDataLayout(), BA->getType(), true); - OpInfo.CallOperand = DAG.getTargetBlockAddress(BA, VT); - } else if (const auto *BB = dyn_cast(OpInfo.CallOperandVal)) { + if (const auto *BB = dyn_cast(OpInfo.CallOperandVal)) { OpInfo.CallOperand = DAG.getBasicBlock(FuncInfo.MBBMap[BB]); } else { OpInfo.CallOperand = getValue(OpInfo.CallOperandVal); @@ -8601,9 +8588,6 @@ OpInfo.ConstraintVT = MVT::Other; } - if (OpInfo.hasMatchingInput()) - ++NumMatchingOps; - if (!HasSideEffect) HasSideEffect = OpInfo.hasMemory(TLI); diff --git a/llvm/test/CodeGen/X86/callbr-asm-bb-exports.ll b/llvm/test/CodeGen/X86/callbr-asm-bb-exports.ll --- a/llvm/test/CodeGen/X86/callbr-asm-bb-exports.ll +++ b/llvm/test/CodeGen/X86/callbr-asm-bb-exports.ll @@ -5,7 +5,10 @@ ; inlineasm_br. Not sure how to get a MachineIR change so this reads the debug ; output from SelectionDAG. -; CHECK: t0: ch = EntryToken +; CHECK: Initial selection DAG: %bb.0 'test:entry' +; CHECK-NEXT: SelectionDAG has 33 nodes: +; CHECK-NEXT: t0: ch = EntryToken +; CHECK-NEXT: t16: i64 = BlockAddress<@test, %fail> 0 ; CHECK-NEXT: t4: i32,ch = CopyFromReg t0, Register:i32 %3 ; CHECK-NEXT: t10: i32 = add t4, Constant:i32<1> ; CHECK-NEXT: t12: ch = CopyToReg t0, Register:i32 %0, t10 @@ -16,7 +19,8 @@ ; CHECK-NEXT: t2: i32,ch = CopyFromReg t0, Register:i32 %2 ; CHECK-NEXT: t8: i32 = add t2, Constant:i32<4> ; CHECK-NEXT: t22: ch,glue = CopyToReg t17, Register:i32 %5, t8 -; CHECK-NEXT: t29: ch,glue = inlineasm_br t22, {{.*}}, t22:1 +; CHECK-NEXT: t30: ch,glue = inlineasm_br t22, {{.*}}, t22:1 +; CHECK-NEXT: t32: ch = br t30, BasicBlock:ch define i32 @test(i32 %a, i32 %b, i32 %c) { entry: diff --git a/llvm/test/CodeGen/X86/callbr-asm-outputs.ll b/llvm/test/CodeGen/X86/callbr-asm-outputs.ll --- a/llvm/test/CodeGen/X86/callbr-asm-outputs.ll +++ b/llvm/test/CodeGen/X86/callbr-asm-outputs.ll @@ -204,3 +204,31 @@ %retval.0 = phi i32 [ %add, %asm.fallthrough2 ], [ -2, %label_true ], [ -1, %asm.fallthrough ], [ -1, %entry ] ret i32 %retval.0 } + +; Test5 - test that we don't rely on a positional constraint. ie. +r in +; GCCAsmStmt being turned into "={esp},0" since after D87279 they're turned +; into "={esp},{esp}". This previously caused an ICE; this test is more so +; about avoiding another ICE than what the actual output is. +define dso_local void @test5() { +; CHECK-LABEL: test5: +; CHECK: # %bb.0: +; CHECK-NEXT: #APP +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: .Ltmp6: # Block address taken +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: retl + %1 = call i32 @llvm.read_register.i32(metadata !3) + %2 = callbr i32 asm "", "={esp},i,{esp},~{dirflag},~{fpsr},~{flags}"(i8* blockaddress(@test5, %4), i32 %1) + to label %3 [label %4] + +3: + call void @llvm.write_register.i32(metadata !3, i32 %2) + br label %4 + +4: + ret void +} + +declare i32 @llvm.read_register.i32(metadata) +declare void @llvm.write_register.i32(metadata, i32) +!3 = !{!"esp"}