Unify the lowering of arguments during SjLj prepare.
authorBill Wendling <isanbard@gmail.com>
Mon, 14 Jul 2014 18:21:11 +0000 (18:21 +0000)
committerBill Wendling <isanbard@gmail.com>
Mon, 14 Jul 2014 18:21:11 +0000 (18:21 +0000)
The 'select true, %arg, undef' instruction can be used for both aggregate and
non-aggregate arguments.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212967 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SjLjEHPrepare.cpp
test/CodeGen/ARM/sjljehprepare-lower-empty-struct.ll

index f53408a0f12476801b647a6828c8094ff82abda1..b0950ded270aa9f6921280ee3d2dc73b598bfe55 100644 (file)
@@ -249,34 +249,16 @@ void SjLjEHPrepare::lowerIncomingArguments(Function &F) {
        ++AI) {
     Type *Ty = AI->getType();
 
-    if (isa<StructType>(Ty) || isa<ArrayType>(Ty)) {
-      // Aggregate types can't be cast, but are legal argument types,
-      // so we have to handle them differently.  We use
-      // select i8 true, %arg, undef to achieve the same goal
-      Value *TrueValue = ConstantInt::getTrue(F.getContext());
-      Value *UndefValue = UndefValue::get(Ty);
-      Instruction *SI = SelectInst::Create(TrueValue, AI, UndefValue,
-                                           AI->getName() + ".tmp",
-                                           AfterAllocaInsPt);
-      AI->replaceAllUsesWith(SI);
-
-      SI->setOperand(1, AI);
-    } else {
-      // This is always a no-op cast because we're casting AI to AI->getType()
-      // so src and destination types are identical. BitCast is the only
-      // possibility.
-      CastInst *NC = new BitCastInst(AI, AI->getType(), AI->getName() + ".tmp",
-                                     AfterAllocaInsPt);
-      AI->replaceAllUsesWith(NC);
-
-      // Set the operand of the cast instruction back to the AllocaInst.
-      // Normally it's forbidden to replace a CastInst's operand because it
-      // could cause the opcode to reflect an illegal conversion. However, we're
-      // replacing it here with the same value it was constructed with.  We do
-      // this because the above replaceAllUsesWith() clobbered the operand, but
-      // we want this one to remain.
-      NC->setOperand(0, AI);
-    }
+    // Use 'select i8 true, %arg, undef' to simulate a 'no-op' instruction.
+    Value *TrueValue = ConstantInt::getTrue(F.getContext());
+    Value *UndefValue = UndefValue::get(Ty);
+    Instruction *SI = SelectInst::Create(TrueValue, AI, UndefValue,
+                                         AI->getName() + ".tmp",
+                                         AfterAllocaInsPt);
+    AI->replaceAllUsesWith(SI);
+
+    // Reset the operand, because it  was clobbered by the RAUW above.
+    SI->setOperand(1, AI);
   }
 }
 
index e26f6350050fc64fb21ec76678d32ee7bb7d51f0..3cf2a08fe35da9d5892b90615eb6dae6043a272c 100644 (file)
@@ -10,7 +10,7 @@
 ; __Unwind_SjLj_Register and actual @bar invocation
 
 
-define i8* @foo({} %c) {
+define i8* @foo(i8 %a, {} %c) {
 entry:
 ; CHECK: bl __Unwind_SjLj_Register
 ; CHECK-NEXT: {{[A-Z][a-zA-Z0-9]*}}: