GlobalISel: make truncate/extend casts uniform

They really should have both types represented, but early variants were created
before MachineInstrs could have multiple types so they're rather ambiguous.

llvm-svn: 279567
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index 9232389..c9499ca 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -141,18 +141,21 @@
       .addUse(CarryIn);
 }
 
-MachineInstrBuilder MachineIRBuilder::buildAnyExtend(LLT Ty, unsigned Res,
-                                                     unsigned Op) {
-  return buildInstr(TargetOpcode::G_ANYEXTEND, Ty).addDef(Res).addUse(Op);
+MachineInstrBuilder MachineIRBuilder::buildAnyExt(ArrayRef<LLT> Tys,
+                                                  unsigned Res, unsigned Op) {
+  validateTruncExt(Tys, true);
+  return buildInstr(TargetOpcode::G_ANYEXT, Tys).addDef(Res).addUse(Op);
 }
 
 MachineInstrBuilder MachineIRBuilder::buildSExt(ArrayRef<LLT> Tys, unsigned Res,
                                                 unsigned Op) {
+  validateTruncExt(Tys, true);
   return buildInstr(TargetOpcode::G_SEXT, Tys).addDef(Res).addUse(Op);
 }
 
 MachineInstrBuilder MachineIRBuilder::buildZExt(ArrayRef<LLT> Tys, unsigned Res,
                                                 unsigned Op) {
+  validateTruncExt(Tys, true);
   return buildInstr(TargetOpcode::G_ZEXT, Tys).addDef(Res).addUse(Op);
 }
 
@@ -216,14 +219,16 @@
   return MIB;
 }
 
-MachineInstrBuilder MachineIRBuilder::buildTrunc(LLT Ty, unsigned Res,
-                                           unsigned Op) {
-  return buildInstr(TargetOpcode::G_TRUNC, Ty).addDef(Res).addUse(Op);
+MachineInstrBuilder MachineIRBuilder::buildTrunc(ArrayRef<LLT> Tys,
+                                                 unsigned Res, unsigned Op) {
+  validateTruncExt(Tys, false);
+  return buildInstr(TargetOpcode::G_TRUNC, Tys).addDef(Res).addUse(Op);
 }
 
-MachineInstrBuilder MachineIRBuilder::buildFPTrunc(LLT Ty, unsigned Res,
-                                           unsigned Op) {
-  return buildInstr(TargetOpcode::G_FPTRUNC, Ty).addDef(Res).addUse(Op);
+MachineInstrBuilder MachineIRBuilder::buildFPTrunc(ArrayRef<LLT> Tys,
+                                                   unsigned Res, unsigned Op) {
+  validateTruncExt(Tys, false);
+  return buildInstr(TargetOpcode::G_FPTRUNC, Tys).addDef(Res).addUse(Op);
 }
 
 MachineInstrBuilder MachineIRBuilder::buildICmp(ArrayRef<LLT> Tys,
@@ -257,3 +262,22 @@
       .addUse(Op0)
       .addUse(Op1);
 }
+
+void MachineIRBuilder::validateTruncExt(ArrayRef<LLT> Tys, bool IsExtend) {
+  assert(Tys.size() == 2 && "cast should have a source and a dest type");
+  LLT DstTy{Tys[0]}, SrcTy{Tys[1]};
+
+  if (DstTy.isVector()) {
+    assert(SrcTy.isVector() && "mismatched cast between vecot and non-vector");
+    assert(SrcTy.getNumElements() == DstTy.getNumElements() &&
+           "different number of elements in a trunc/ext");
+  } else
+    assert(DstTy.isScalar() && SrcTy.isScalar() && "invalid extend/trunc");
+
+  if (IsExtend)
+    assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() &&
+           "invalid narrowing extend");
+  else
+    assert(DstTy.getSizeInBits() < SrcTy.getSizeInBits() &&
+           "invalid widening trunc");
+}
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
index 2fb7f24..c7d30cf 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
@@ -107,6 +107,7 @@
 MachineLegalizeHelper::LegalizeResult
 MachineLegalizeHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx,
                                    LLT WideTy) {
+  LLT Ty = MI.getType();
   unsigned WideSize = WideTy.getSizeInBits();
   MIRBuilder.setInstr(MI);
 
@@ -124,34 +125,34 @@
     // original type.
     unsigned Src1Ext = MRI.createGenericVirtualRegister(WideSize);
     unsigned Src2Ext = MRI.createGenericVirtualRegister(WideSize);
-    MIRBuilder.buildAnyExtend(WideTy, Src1Ext, MI.getOperand(1).getReg());
-    MIRBuilder.buildAnyExtend(WideTy, Src2Ext, MI.getOperand(2).getReg());
+    MIRBuilder.buildAnyExt({WideTy, Ty}, Src1Ext, MI.getOperand(1).getReg());
+    MIRBuilder.buildAnyExt({WideTy, Ty}, Src2Ext, MI.getOperand(2).getReg());
 
     unsigned DstExt = MRI.createGenericVirtualRegister(WideSize);
     MIRBuilder.buildInstr(MI.getOpcode(), WideTy)
       .addDef(DstExt).addUse(Src1Ext).addUse(Src2Ext);
 
-    MIRBuilder.buildTrunc(MI.getType(), MI.getOperand(0).getReg(), DstExt);
+    MIRBuilder.buildTrunc({Ty, WideTy}, MI.getOperand(0).getReg(), DstExt);
     MI.eraseFromParent();
     return Legalized;
   }
   case TargetOpcode::G_LOAD: {
-    assert(alignTo(MI.getType().getSizeInBits(), 8) == WideSize &&
+    assert(alignTo(Ty.getSizeInBits(), 8) == WideSize &&
            "illegal to increase number of bytes loaded");
 
     unsigned DstExt = MRI.createGenericVirtualRegister(WideSize);
     MIRBuilder.buildLoad(WideTy, MI.getType(1), DstExt,
                          MI.getOperand(1).getReg(), **MI.memoperands_begin());
-    MIRBuilder.buildTrunc(MI.getType(), MI.getOperand(0).getReg(), DstExt);
+    MIRBuilder.buildTrunc({Ty, WideTy}, MI.getOperand(0).getReg(), DstExt);
     MI.eraseFromParent();
     return Legalized;
   }
   case TargetOpcode::G_STORE: {
-    assert(alignTo(MI.getType().getSizeInBits(), 8) == WideSize &&
+    assert(alignTo(Ty.getSizeInBits(), 8) == WideSize &&
            "illegal to increase number of bytes modified by a store");
 
     unsigned SrcExt = MRI.createGenericVirtualRegister(WideSize);
-    MIRBuilder.buildAnyExtend(WideTy, SrcExt, MI.getOperand(0).getReg());
+    MIRBuilder.buildAnyExt({WideTy, Ty}, SrcExt, MI.getOperand(0).getReg());
     MIRBuilder.buildStore(WideTy, MI.getType(1), SrcExt,
                           MI.getOperand(1).getReg(), **MI.memoperands_begin());
     MI.eraseFromParent();
@@ -160,20 +161,20 @@
   case TargetOpcode::G_CONSTANT: {
     unsigned DstExt = MRI.createGenericVirtualRegister(WideSize);
     MIRBuilder.buildConstant(WideTy, DstExt, MI.getOperand(1).getImm());
-    MIRBuilder.buildTrunc(MI.getType(), MI.getOperand(0).getReg(), DstExt);
+    MIRBuilder.buildTrunc({Ty, WideTy}, MI.getOperand(0).getReg(), DstExt);
     MI.eraseFromParent();
     return Legalized;
   }
   case TargetOpcode::G_FCONSTANT: {
     unsigned DstExt = MRI.createGenericVirtualRegister(WideSize);
     MIRBuilder.buildFConstant(WideTy, DstExt, *MI.getOperand(1).getFPImm());
-    MIRBuilder.buildFPTrunc(MI.getType(), MI.getOperand(0).getReg(), DstExt);
+    MIRBuilder.buildFPTrunc({Ty, WideTy}, MI.getOperand(0).getReg(), DstExt);
     MI.eraseFromParent();
     return Legalized;
   }
   case TargetOpcode::G_BRCOND: {
     unsigned TstExt = MRI.createGenericVirtualRegister(WideSize);
-    MIRBuilder.buildAnyExtend(WideTy, TstExt, MI.getOperand(0).getReg());
+    MIRBuilder.buildAnyExt({WideTy, Ty}, TstExt, MI.getOperand(0).getReg());
     MIRBuilder.buildBrCond(WideTy, TstExt, *MI.getOperand(1).getMBB());
     MI.eraseFromParent();
     return Legalized;
@@ -185,7 +186,7 @@
           {WideTy, MI.getType(1)},
           static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()),
           TstExt, MI.getOperand(2).getReg(), MI.getOperand(3).getReg());
-      MIRBuilder.buildTrunc(MI.getType(), MI.getOperand(0).getReg(), TstExt);
+      MIRBuilder.buildTrunc({Ty, WideTy}, MI.getOperand(0).getReg(), TstExt);
       MI.eraseFromParent();
       return Legalized;
     } else {
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp b/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp
index 6ac0c80..6c00810 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp
@@ -27,7 +27,7 @@
 MachineLegalizer::MachineLegalizer() : TablesInitialized(false) {
   // FIXME: these two can be legalized to the fundamental load/store Jakob
   // proposed. Once loads & stores are supported.
-  DefaultActions[TargetOpcode::G_ANYEXTEND] = Legal;
+  DefaultActions[TargetOpcode::G_ANYEXT] = Legal;
   DefaultActions[TargetOpcode::G_TRUNC] = Legal;
 
   DefaultActions[TargetOpcode::G_INTRINSIC] = Legal;