[llvm] 7802be4 - [SelDag] Add FREEZE

Juneyoung Lee via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 24 07:05:07 PDT 2020


Author: Juneyoung Lee
Date: 2020-03-24T23:04:58+09:00
New Revision: 7802be4a3d86743242273593d43a78df84ece8c1

URL: https://github.com/llvm/llvm-project/commit/7802be4a3d86743242273593d43a78df84ece8c1
DIFF: https://github.com/llvm/llvm-project/commit/7802be4a3d86743242273593d43a78df84ece8c1.diff

LOG: [SelDag] Add FREEZE

Summary:
- Add FREEZE node to SelDag
- Lower FreezeInst (in IR) to FREEZE node
- Add Legalization for FREEZE node

Reviewers: qcolombet, bogner, efriedma, lebedev.ri, nlopes, craig.topper, arsenm

Reviewed By: lebedev.ri

Subscribers: wdng, xbolva00, Petar.Avramovic, liuz, lkail, dylanmckay, hiraditya, Jim, arsenm, craig.topper, RKSimon, spatel, lebedev.ri, regehr, trentxintong, nlopes, mkuper, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D29014

Added: 
    llvm/test/CodeGen/X86/fast-isel-freeze.ll
    llvm/test/CodeGen/X86/freeze-legalize.ll
    llvm/test/CodeGen/X86/freeze.ll

Modified: 
    llvm/include/llvm/CodeGen/FastISel.h
    llvm/include/llvm/CodeGen/ISDOpcodes.h
    llvm/include/llvm/CodeGen/SelectionDAGISel.h
    llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
    llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
    llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
    llvm/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
    llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
    llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
    llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
    llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
    llvm/lib/CodeGen/TargetLoweringBase.cpp
    llvm/test/CodeGen/X86/fast-isel.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/FastISel.h b/llvm/include/llvm/CodeGen/FastISel.h
index d9c680392e50..326a7eb2e938 100644
--- a/llvm/include/llvm/CodeGen/FastISel.h
+++ b/llvm/include/llvm/CodeGen/FastISel.h
@@ -534,6 +534,7 @@ class FastISel {
   bool selectCall(const User *I);
   bool selectIntrinsicCall(const IntrinsicInst *II);
   bool selectBitCast(const User *I);
+  bool selectFreeze(const User *I);
   bool selectCast(const User *I, unsigned Opcode);
   bool selectExtractValue(const User *U);
   bool selectInsertValue(const User *I);

diff  --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h
index 4bc8d7bd42f0..17e8f53c2300 100644
--- a/llvm/include/llvm/CodeGen/ISDOpcodes.h
+++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h
@@ -178,6 +178,11 @@ namespace ISD {
     /// UNDEF - An undefined node.
     UNDEF,
 
+    // FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or
+    // is evaluated to UNDEF), or returns VAL otherwise. Note that each
+    // read of UNDEF can yield 
diff erent value, but FREEZE(UNDEF) cannot.
+    FREEZE,
+
     /// EXTRACT_ELEMENT - This is used to get the lower or upper (determined by
     /// a Constant, which is required to be operand #1) half of the integer or
     /// float value specified as operand #0.  This is only for use before

diff  --git a/llvm/include/llvm/CodeGen/SelectionDAGISel.h b/llvm/include/llvm/CodeGen/SelectionDAGISel.h
index 52c3e0c6148a..084badcbe029 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAGISel.h
@@ -324,6 +324,8 @@ class SelectionDAGISel : public MachineFunctionPass {
   void Select_UNDEF(SDNode *N);
   void CannotYetSelect(SDNode *N);
 
+  void Select_FREEZE(SDNode *N);
+
 private:
   void DoInstructionSelection();
   SDNode *MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTList,

diff  --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index ada09092c478..461d481c822f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -1572,6 +1572,27 @@ bool FastISel::selectBitCast(const User *I) {
   return true;
 }
 
+bool FastISel::selectFreeze(const User *I) {
+  Register Reg = getRegForValue(I->getOperand(0));
+  if (!Reg)
+    // Unhandled operand.
+    return false;
+
+  EVT ETy = TLI.getValueType(DL, I->getOperand(0)->getType());
+  if (ETy == MVT::Other || !TLI.isTypeLegal(ETy))
+    // Unhandled type, bail out.
+    return false;
+
+  MVT Ty = ETy.getSimpleVT();
+  const TargetRegisterClass *TyRegClass = TLI.getRegClassFor(Ty);
+  Register ResultReg = createResultReg(TyRegClass);
+  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
+          TII.get(TargetOpcode::COPY), ResultReg).addReg(Reg);
+
+  updateValueMap(I, ResultReg);
+  return true;
+}
+
 // Remove local value instructions starting from the instruction after
 // SavedLastLocalValue to the current function insert point.
 void FastISel::removeDeadLocalValueCode(MachineInstr *SavedLastLocalValue)
@@ -1913,6 +1934,9 @@ bool FastISel::selectOperator(const User *I, unsigned Opcode) {
   case Instruction::ExtractValue:
     return selectExtractValue(I);
 
+  case Instruction::Freeze:
+    return selectFreeze(I);
+
   case Instruction::PHI:
     llvm_unreachable("FastISel shouldn't visit PHI nodes!");
 

diff  --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 3955490a3f85..0248b5121e3f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -201,6 +201,10 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
   case ISD::VECREDUCE_UMIN:
     Res = PromoteIntRes_VECREDUCE(N);
     break;
+
+  case ISD::FREEZE:
+    Res = PromoteIntRes_FREEZE(N);
+    break;
   }
 
   // If the result is null then the sub-method took care of registering it.
@@ -401,6 +405,12 @@ static EVT getShiftAmountTyForConstant(EVT VT, const TargetLowering &TLI,
   return ShiftVT;
 }
 
+SDValue DAGTypeLegalizer::PromoteIntRes_FREEZE(SDNode *N) {
+  SDValue V = GetPromotedInteger(N->getOperand(0));
+  return DAG.getNode(ISD::FREEZE, SDLoc(N),
+                     V.getValueType(), V);
+}
+
 SDValue DAGTypeLegalizer::PromoteIntRes_BSWAP(SDNode *N) {
   SDValue Op = GetPromotedInteger(N->getOperand(0));
   EVT OVT = N->getValueType(0);
@@ -1868,6 +1878,7 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
   case ISD::SELECT:       SplitRes_SELECT(N, Lo, Hi); break;
   case ISD::SELECT_CC:    SplitRes_SELECT_CC(N, Lo, Hi); break;
   case ISD::UNDEF:        SplitRes_UNDEF(N, Lo, Hi); break;
+  case ISD::FREEZE:       SplitRes_FREEZE(N, Lo, Hi); break;
 
   case ISD::BITCAST:            ExpandRes_BITCAST(N, Lo, Hi); break;
   case ISD::BUILD_PAIR:         ExpandRes_BUILD_PAIR(N, Lo, Hi); break;

diff  --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index 8126c42e4498..aee4ab1fcd61 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -309,6 +309,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
   SDValue PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N);
   SDValue PromoteIntRes_FP_TO_XINT(SDNode *N);
   SDValue PromoteIntRes_FP_TO_FP16(SDNode *N);
+  SDValue PromoteIntRes_FREEZE(SDNode *N);
   SDValue PromoteIntRes_INT_EXTEND(SDNode *N);
   SDValue PromoteIntRes_LOAD(LoadSDNode *N);
   SDValue PromoteIntRes_MLOAD(MaskedLoadSDNode *N);
@@ -961,6 +962,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
   void SplitRes_SELECT      (SDNode *N, SDValue &Lo, SDValue &Hi);
   void SplitRes_SELECT_CC   (SDNode *N, SDValue &Lo, SDValue &Hi);
   void SplitRes_UNDEF       (SDNode *N, SDValue &Lo, SDValue &Hi);
+  void SplitRes_FREEZE      (SDNode *N, SDValue &Lo, SDValue &Hi);
 
   void SplitVSETCC(const SDNode *N);
 

diff  --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
index ad3e02f9921a..8231a320b4f3 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
@@ -558,3 +558,12 @@ void DAGTypeLegalizer::SplitRes_UNDEF(SDNode *N, SDValue &Lo, SDValue &Hi) {
   Lo = DAG.getUNDEF(LoVT);
   Hi = DAG.getUNDEF(HiVT);
 }
+
+void DAGTypeLegalizer::SplitRes_FREEZE(SDNode *N, SDValue &Lo, SDValue &Hi) {
+  SDValue L, H;
+  SDLoc dl(N);
+  GetSplitOp(N->getOperand(0), L, H);
+
+  Lo = DAG.getNode(ISD::FREEZE, dl, L.getValueType(), L);
+  Hi = DAG.getNode(ISD::FREEZE, dl, H.getValueType(), H);
+}

diff  --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 09934bbb29fe..afed415af5ed 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -89,6 +89,7 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {
   case ISD::FLOG2:
   case ISD::FNEARBYINT:
   case ISD::FNEG:
+  case ISD::FREEZE:
   case ISD::FP_EXTEND:
   case ISD::FP_TO_SINT:
   case ISD::FP_TO_UINT:
@@ -879,6 +880,7 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
   case ISD::FLOG2:
   case ISD::FNEARBYINT:
   case ISD::FNEG:
+  case ISD::FREEZE:
   case ISD::FP_EXTEND:
   case ISD::FP_ROUND:
   case ISD::FP_TO_SINT:
@@ -2831,6 +2833,7 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
   case ISD::CTTZ:
   case ISD::CTTZ_ZERO_UNDEF:
   case ISD::FNEG:
+  case ISD::FREEZE:
   case ISD::FCANONICALIZE:
     Res = WidenVecRes_Unary(N);
     break;

diff  --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 06fe247b0270..1ad86208ed4e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -10690,6 +10690,22 @@ void SelectionDAGBuilder::visitSwitch(const SwitchInst &SI) {
 }
 
 void SelectionDAGBuilder::visitFreeze(const FreezeInst &I) {
-  SDValue N = getValue(I.getOperand(0));
-  setValue(&I, N);
+  SDNodeFlags Flags;
+
+  SDValue Op = getValue(I.getOperand(0));
+  if (I.getOperand(0)->getType()->isAggregateType()) {
+    EVT VT = Op.getValueType();
+    SmallVector<SDValue, 1> Values;
+    for (unsigned i = 0; i < Op.getNumOperands(); ++i) {
+      SDValue Arg(Op.getNode(), i);
+      SDValue UnNodeValue = DAG.getNode(ISD::FREEZE, getCurSDLoc(), VT, Arg, Flags);
+      Values.push_back(UnNodeValue);
+    }
+    SDValue MergedValue = DAG.getMergeValues(Values, getCurSDLoc());
+    setValue(&I, MergedValue);
+  } else {
+    SDValue UnNodeValue = DAG.getNode(ISD::FREEZE, getCurSDLoc(), Op.getValueType(),
+                                      Op, Flags);
+    setValue(&I, UnNodeValue);
+  }
 }

diff  --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
index 0fd132f03af8..aca462f56674 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -392,6 +392,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
   case ISD::GC_TRANSITION_START:        return "gc_transition.start";
   case ISD::GC_TRANSITION_END:          return "gc_transition.end";
   case ISD::GET_DYNAMIC_AREA_OFFSET:    return "get.dynamic.area.offset";
+  case ISD::FREEZE:                     return "freeze";
 
   // Bit manipulation
   case ISD::ABS:                        return "abs";

diff  --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 51b2439dddc3..6fa6bde047c5 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -2290,6 +2290,14 @@ void SelectionDAGISel::Select_UNDEF(SDNode *N) {
   CurDAG->SelectNodeTo(N, TargetOpcode::IMPLICIT_DEF, N->getValueType(0));
 }
 
+void SelectionDAGISel::Select_FREEZE(SDNode *N) {
+  // TODO: We don't have FREEZE pseudo-instruction in MachineInstr-level now.
+  // If FREEZE instruction is added later, the code below must be changed as
+  // well.
+  CurDAG->SelectNodeTo(N, TargetOpcode::COPY, N->getValueType(0),
+                       N->getOperand(0));
+}
+
 /// GetVBR - decode a vbr encoding whose top bit is set.
 LLVM_ATTRIBUTE_ALWAYS_INLINE static inline uint64_t
 GetVBR(uint64_t Val, const unsigned char *MatcherTable, unsigned &Idx) {
@@ -2826,6 +2834,9 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
   case ISD::UNDEF:
     Select_UNDEF(NodeToMatch);
     return;
+  case ISD::FREEZE:
+    Select_FREEZE(NodeToMatch);
+    return;
   }
 
   assert(!NodeToMatch->isMachineOpcode() && "Node already selected!");

diff  --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp
index 436857d6b215..27440b2dd02c 100644
--- a/llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -1657,7 +1657,7 @@ int TargetLoweringBase::InstructionOpcodeToISD(unsigned Opcode) const {
   case ExtractValue:   return ISD::MERGE_VALUES;
   case InsertValue:    return ISD::MERGE_VALUES;
   case LandingPad:     return 0;
-  case Freeze:         return 0;
+  case Freeze:         return ISD::FREEZE;
   }
 
   llvm_unreachable("Unknown instruction type encountered!");

diff  --git a/llvm/test/CodeGen/X86/fast-isel-freeze.ll b/llvm/test/CodeGen/X86/fast-isel-freeze.ll
new file mode 100644
index 000000000000..fee53ca93f54
--- /dev/null
+++ b/llvm/test/CodeGen/X86/fast-isel-freeze.ll
@@ -0,0 +1,21 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s                               -mtriple=x86_64-unknown-linux | FileCheck %s --check-prefix=SDAG
+; RUN: llc < %s -fast-isel -fast-isel-abort=1 -mtriple=x86_64-unknown-linux | FileCheck %s --check-prefix=FAST
+
+define i32 @freeze(i32 %t) {
+; SDAG-LABEL: freeze:
+; SDAG:       # %bb.0:
+; SDAG-NEXT:    movl $10, %eax
+; SDAG-NEXT:    xorl %edi, %eax
+; SDAG-NEXT:    retq
+;
+; FAST-LABEL: freeze:
+; FAST:       # %bb.0:
+; FAST-NEXT:    movl $10, %eax
+; FAST-NEXT:    xorl %edi, %eax
+; FAST-NEXT:    retq
+  %1 = freeze i32 %t
+  %2 = freeze i32 10
+  %3 = xor i32 %1, %2
+  ret i32 %3
+}

diff  --git a/llvm/test/CodeGen/X86/fast-isel.ll b/llvm/test/CodeGen/X86/fast-isel.ll
index dbc13ba7ed78..e9a8a6b53950 100644
--- a/llvm/test/CodeGen/X86/fast-isel.ll
+++ b/llvm/test/CodeGen/X86/fast-isel.ll
@@ -99,6 +99,11 @@ define void @load_store_i1(i1* %p, i1* %q) nounwind {
   ret void
 }
 
+define void @freeze_i32(i32 %x) {
+  %t = freeze i32 %x
+  ret void
+}
+
 @crash_test1x = external global <2 x i32>, align 8
 
 define void @crash_test1() nounwind ssp {

diff  --git a/llvm/test/CodeGen/X86/freeze-legalize.ll b/llvm/test/CodeGen/X86/freeze-legalize.ll
new file mode 100644
index 000000000000..6bbd0b8e5949
--- /dev/null
+++ b/llvm/test/CodeGen/X86/freeze-legalize.ll
@@ -0,0 +1,87 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; Make sure that seldag legalization works correctly for freeze instruction.
+; RUN: llc -mtriple=i386-apple-darwin < %s 2>&1 | FileCheck %s
+
+define i64 @expand(i32 %x) {
+; CHECK-LABEL: expand:
+; CHECK:       ## %bb.0:
+; CHECK-NEXT:    movl $303174162, %eax ## imm = 0x12121212
+; CHECK-NEXT:    movl $875836468, %ecx ## imm = 0x34343434
+; CHECK-NEXT:    movl $1448498774, %edx ## imm = 0x56565656
+; CHECK-NEXT:    xorl %eax, %edx
+; CHECK-NEXT:    movl $2021161080, %eax ## imm = 0x78787878
+; CHECK-NEXT:    xorl %ecx, %eax
+; CHECK-NEXT:    retl
+  %y1 = freeze i64 1302123111658042420 ; 0x1212121234343434
+  %y2 = freeze i64 6221254864647256184 ; 0x5656565678787878
+  %t2 = xor i64 %y1, %y2
+  ret i64 %t2
+}
+
+
+define <2 x i64> @expand_vec(i32 %x) nounwind {
+; CHECK-LABEL: expand_vec:
+; CHECK:       ## %bb.0:
+; CHECK-NEXT:    pushl %ebx
+; CHECK-NEXT:    pushl %edi
+; CHECK-NEXT:    pushl %esi
+; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK-NEXT:    movl $16843009, %ecx ## imm = 0x1010101
+; CHECK-NEXT:    movl $589505315, %edx ## imm = 0x23232323
+; CHECK-NEXT:    movl $303174162, %esi ## imm = 0x12121212
+; CHECK-NEXT:    movl $875836468, %edi ## imm = 0x34343434
+; CHECK-NEXT:    movl $1162167621, %ebx ## imm = 0x45454545
+; CHECK-NEXT:    xorl %ecx, %ebx
+; CHECK-NEXT:    movl $1734829927, %ecx ## imm = 0x67676767
+; CHECK-NEXT:    xorl %edx, %ecx
+; CHECK-NEXT:    movl $1448498774, %edx ## imm = 0x56565656
+; CHECK-NEXT:    xorl %esi, %edx
+; CHECK-NEXT:    movl $2021161080, %esi ## imm = 0x78787878
+; CHECK-NEXT:    xorl %edi, %esi
+; CHECK-NEXT:    movl %ebx, 12(%eax)
+; CHECK-NEXT:    movl %ecx, 8(%eax)
+; CHECK-NEXT:    movl %edx, 4(%eax)
+; CHECK-NEXT:    movl %esi, (%eax)
+; CHECK-NEXT:    popl %esi
+; CHECK-NEXT:    popl %edi
+; CHECK-NEXT:    popl %ebx
+; CHECK-NEXT:    retl $4
+  ; <0x1212121234343434, 0x101010123232323>
+  %y1 = freeze <2 x i64> <i64 1302123111658042420, i64 72340173410738979>
+  ; <0x5656565678787878, 0x4545454567676767>
+  %y2 = freeze <2 x i64> <i64 6221254864647256184, i64 4991471926399952743>
+  %t2 = xor <2 x i64> %y1, %y2
+  ret <2 x i64> %t2
+}
+
+define i10 @promote() {
+; CHECK-LABEL: promote:
+; CHECK:       ## %bb.0:
+; CHECK-NEXT:    movw $682, %cx ## imm = 0x2AA
+; CHECK-NEXT:    movw $992, %ax ## imm = 0x3E0
+; CHECK-NEXT:    addl %ecx, %eax
+; CHECK-NEXT:    ## kill: def $ax killed $ax killed $eax
+; CHECK-NEXT:    retl
+  %a = freeze i10 682
+  %b = freeze i10 992
+  %res = add i10 %a, %b
+  ret i10 %res
+}
+
+define <2 x i10> @promote_vec() {
+; CHECK-LABEL: promote_vec:
+; CHECK:       ## %bb.0:
+; CHECK-NEXT:    movw $125, %ax
+; CHECK-NEXT:    movw $682, %cx ## imm = 0x2AA
+; CHECK-NEXT:    movw $393, %dx ## imm = 0x189
+; CHECK-NEXT:    addl %eax, %edx
+; CHECK-NEXT:    movw $992, %ax ## imm = 0x3E0
+; CHECK-NEXT:    addl %ecx, %eax
+; CHECK-NEXT:    ## kill: def $ax killed $ax killed $eax
+; CHECK-NEXT:    ## kill: def $dx killed $dx killed $edx
+; CHECK-NEXT:    retl
+  %a = freeze <2 x i10> <i10 682, i10 125>
+  %b = freeze <2 x i10> <i10 992, i10 393>
+  %res = add <2 x i10> %a, %b
+  ret <2 x i10> %res
+}

diff  --git a/llvm/test/CodeGen/X86/freeze.ll b/llvm/test/CodeGen/X86/freeze.ll
new file mode 100644
index 000000000000..9ae9661a148c
--- /dev/null
+++ b/llvm/test/CodeGen/X86/freeze.ll
@@ -0,0 +1,90 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s 2>&1 | FileCheck %s --check-prefix=X86ASM
+
+%struct.T = type { i32, i32 }
+
+define i32 @freeze_int() {
+; X86ASM-LABEL: freeze_int:
+; X86ASM:       # %bb.0:
+; X86ASM-NEXT:    imull %eax, %eax
+; X86ASM-NEXT:    retq
+  %y1 = freeze i32 undef
+  %t1 = mul i32 %y1, %y1
+  ret i32 %t1
+}
+
+define i5 @freeze_int2() {
+; X86ASM-LABEL: freeze_int2:
+; X86ASM:       # %bb.0:
+; X86ASM-NEXT:    mulb %al
+; X86ASM-NEXT:    retq
+  %y1 = freeze i5 undef
+  %t1 = mul i5 %y1, %y1
+  ret i5 %t1
+}
+
+define float @freeze_float() {
+; X86ASM-LABEL: freeze_float:
+; X86ASM:       # %bb.0:
+; X86ASM-NEXT:    addss %xmm0, %xmm0
+; X86ASM-NEXT:    retq
+  %y1 = freeze float undef
+  %t1 = fadd float %y1, %y1
+  ret float %t1
+}
+
+define <2 x i32> @freeze_ivec() {
+; X86ASM-LABEL: freeze_ivec:
+; X86ASM:       # %bb.0:
+; X86ASM-NEXT:    paddd %xmm0, %xmm0
+; X86ASM-NEXT:    retq
+  %y1 = freeze <2 x i32> undef
+  %t1 = add <2 x i32> %y1, %y1
+  ret <2 x i32> %t1
+}
+
+define i8* @freeze_ptr() {
+; X86ASM-LABEL: freeze_ptr:
+; X86ASM:       # %bb.0:
+; X86ASM-NEXT:    addq $4, %rax
+; X86ASM-NEXT:    retq
+  %y1 = freeze i8* undef
+  %t1 = getelementptr i8, i8* %y1, i64 4
+  ret i8* %t1
+}
+
+define i32 @freeze_struct() {
+; X86ASM-LABEL: freeze_struct:
+; X86ASM:       # %bb.0:
+; X86ASM-NEXT:    addl %eax, %eax
+; X86ASM-NEXT:    retq
+  %y1 = freeze %struct.T undef
+  %v1 = extractvalue %struct.T %y1, 0
+  %v2 = extractvalue %struct.T %y1, 1
+  %t1 = add i32 %v1, %v2
+  ret i32 %t1
+}
+
+define i32 @freeze_anonstruct() {
+; X86ASM-LABEL: freeze_anonstruct:
+; X86ASM:       # %bb.0:
+; X86ASM-NEXT:    addl %eax, %eax
+; X86ASM-NEXT:    retq
+  %y1 = freeze {i32, i32} undef
+  %v1 = extractvalue {i32, i32} %y1, 0
+  %v2 = extractvalue {i32, i32} %y1, 1
+  %t1 = add i32 %v1, %v2
+  ret i32 %t1
+}
+
+define i64 @freeze_array() {
+; X86ASM-LABEL: freeze_array:
+; X86ASM:       # %bb.0:
+; X86ASM-NEXT:    addq %rax, %rax
+; X86ASM-NEXT:    retq
+  %y1 = freeze [2 x i64] undef
+  %v1 = extractvalue [2 x i64] %y1, 0
+  %v2 = extractvalue [2 x i64] %y1, 1
+  %t1 = add i64 %v1, %v2
+  ret i64 %t1
+}


        


More information about the llvm-commits mailing list