llvm.org GIT mirror llvm / e4957fb
Add the heuristic to differentiate SSPStrong from SSPRequired. The requirements of the strong heuristic are: * A Protector is required for functions which contain an array, regardless of type or length. * A Protector is required for functions which contain a structure/union which contains an array, regardless of type or length. Note, there is no limit to the depth of nesting. * A protector is required when the address of a local variable (i.e., stack based variable) is exposed. (E.g., such as through a local whose address is taken as part of the RHS of an assignment or a local whose address is taken as part of a function argument.) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173231 91177308-0d34-0410-b5e6-96231b3b80d8 Bill Wendling 7 years ago
3 changed file(s) with 2635 addition(s) and 38 deletion(s). Raw diff Collapse all Expand all
824824 placed on the stack before the local variables that's checked upon
825825 return from the function to see if it has been overwritten. A
826826 heuristic is used to determine if a function needs stack protectors
827 or not.
827 or not. The heuristic used will enable protectors for functions with:
828 - Character arrays larger than ``ssp-buffer-size`` (default 8).
829 - Aggregates containing character arrays larger than ``ssp-buffer-size``.
830 - Calls to alloca() with variable sizes or constant sizes greater than
831 ``ssp-buffer-size``.
828832
829833 If a function that has an ``ssp`` attribute is inlined into a
830834 function that doesn't have an ``ssp`` attribute, then the resulting
840844 an ``sspreq`` attribute.
841845 ``sspstrong``
842846 This attribute indicates that the function should emit a stack smashing
843 protector. Currently this attribute has the same effect as
844 ``sspreq``. This overrides the ``ssp`` function attribute.
847 protector. This attribute causes a strong heuristic to be used when
848 determining if a function needs stack protectors. The strong heuristic
849 will enable protectors for functions with:
850 - Arrays of any size and type
851 - Aggregates containing an array of any size and type.
852 - Calls to alloca().
853 - Local variables that have had their address taken.
854
855 This overrides the ``ssp`` function attribute.
845856
846857 If a function that has an ``sspstrong`` attribute is inlined into a
847858 function that doesn't have an ``sspstrong`` attribute, then the
1515
1616 #define DEBUG_TYPE "stack-protector"
1717 #include "llvm/CodeGen/Passes.h"
18 #include "llvm/ADT/SmallPtrSet.h"
19 #include "llvm/ADT/Statistic.h"
1820 #include "llvm/ADT/Triple.h"
1921 #include "llvm/Analysis/Dominators.h"
2022 #include "llvm/IR/Attributes.h"
3133 #include "llvm/Target/TargetOptions.h"
3234 using namespace llvm;
3335
36 STATISTIC(NumFunProtected, "Number of functions protected");
37 STATISTIC(NumAddrTaken, "Number of local variables that have their address"
38 " taken.");
39
3440 namespace {
3541 class StackProtector : public FunctionPass {
3642 /// TLI - Keep a pointer of a TargetLowering to consult for determining
4147 Module *M;
4248
4349 DominatorTree *DT;
50
51 /// VisitedPHIs - The set of PHI nodes visited when determining
52 /// if a variable's reference has been taken. This set
53 /// is maintained to ensure we don't visit the same PHI node multiple
54 /// times.
55 SmallPtrSet VisitedPHIs;
4456
4557 /// InsertStackProtectors - Insert code into the prologue and epilogue of
4658 /// the function.
5769 /// ContainsProtectableArray - Check whether the type either is an array or
5870 /// contains an array of sufficient size so that we need stack protectors
5971 /// for it.
60 bool ContainsProtectableArray(Type *Ty, bool InStruct = false) const;
72 bool ContainsProtectableArray(Type *Ty, bool Strong = false,
73 bool InStruct = false) const;
74
75 /// \brief Check whether a stack allocation has its address taken.
76 bool HasAddressTaken(const Instruction *AI);
6177
6278 /// RequiresStackProtector - Check whether or not this function needs a
6379 /// stack protector based upon the stack protector level.
64 bool RequiresStackProtector() const;
80 bool RequiresStackProtector();
6581 public:
6682 static char ID; // Pass identification, replacement for typeid.
6783 StackProtector() : FunctionPass(ID), TLI(0) {
95111
96112 if (!RequiresStackProtector()) return false;
97113
114 ++NumFunProtected;
98115 return InsertStackProtectors();
99116 }
100117
101118 /// ContainsProtectableArray - Check whether the type either is an array or
102119 /// contains a char array of sufficient size so that we need stack protectors
103120 /// for it.
104 bool StackProtector::ContainsProtectableArray(Type *Ty, bool InStruct) const {
121 bool StackProtector::ContainsProtectableArray(Type *Ty, bool Strong,
122 bool InStruct) const {
105123 if (!Ty) return false;
106124 if (ArrayType *AT = dyn_cast(Ty)) {
125 // In strong mode any array, regardless of type and size, triggers a
126 // protector
127 if (Strong)
128 return true;
107129 const TargetMachine &TM = TLI->getTargetMachine();
108130 if (!AT->getElementType()->isIntegerTy(8)) {
109131 Triple Trip(TM.getTargetTriple());
125147
126148 for (StructType::element_iterator I = ST->element_begin(),
127149 E = ST->element_end(); I != E; ++I)
128 if (ContainsProtectableArray(*I, true))
150 if (ContainsProtectableArray(*I, Strong, true))
129151 return true;
130152
131153 return false;
132154 }
133155
134 /// RequiresStackProtector - Check whether or not this function needs a stack
135 /// protector based upon the stack protector level. The heuristic we use is to
136 /// add a guard variable to functions that call alloca, and functions with
137 /// buffers larger than SSPBufferSize bytes.
138 bool StackProtector::RequiresStackProtector() const {
156 bool StackProtector::HasAddressTaken(const Instruction *AI) {
157 for (Value::const_use_iterator UI = AI->use_begin(), UE = AI->use_end();
158 UI != UE; ++UI) {
159 const User *U = *UI;
160 if (const StoreInst *SI = dyn_cast(U)) {
161 if (AI == SI->getValueOperand())
162 return true;
163 } else if (const PtrToIntInst *SI = dyn_cast(U)) {
164 if (AI == SI->getOperand(0))
165 return true;
166 } else if (isa(U)) {
167 return true;
168 } else if (isa(U)) {
169 return true;
170 } else if (const SelectInst *SI = dyn_cast(U)) {
171 if (HasAddressTaken(SI))
172 return true;
173 } else if (const PHINode *PN = dyn_cast(U)) {
174 // Keep track of what PHI nodes we have already visited to ensure
175 // they are only visited once.
176 if (VisitedPHIs.insert(PN))
177 if (HasAddressTaken(PN))
178 return true;
179 } else if (const GetElementPtrInst *GEP = dyn_cast(U)) {
180 if (HasAddressTaken(GEP))
181 return true;
182 } else if (const BitCastInst *BI = dyn_cast(U)) {
183 if (HasAddressTaken(BI))
184 return true;
185 }
186 }
187 return false;
188 }
189
190 /// \brief Check whether or not this function needs a stack protector based
191 /// upon the stack protector level.
192 ///
193 /// We use two heuristics: a standard (ssp) and strong (sspstrong).
194 /// The standard heuristic which will add a guard variable to functions that
195 /// call alloca with a either a variable size or a size >= SSPBufferSize,
196 /// functions with character buffers larger than SSPBufferSize, and functions
197 /// with aggregates containing character buffers larger than SSPBufferSize. The
198 /// strong heuristic will add a guard variables to functions that call alloca
199 /// regardless of size, functions with any buffer regardless of type and size,
200 /// functions with aggregates that contain any buffer regardless of type and
201 /// size, and functions that contain stack-based variables that have had their
202 /// address taken.
203 bool StackProtector::RequiresStackProtector() {
204 bool Strong = false;
139205 if (F->getAttributes().hasAttribute(AttributeSet::FunctionIndex,
140206 Attribute::StackProtectReq))
141207 return true;
142
143 // FIXME: Dummy SSP-strong implementation. Default to required until
144 // strong heuristic is implemented.
145 if (F->getAttributes().hasAttribute(AttributeSet::FunctionIndex,
146 Attribute::StackProtectStrong))
147 return true;
148
149 if (!F->getAttributes().hasAttribute(AttributeSet::FunctionIndex,
150 Attribute::StackProtect))
208 else if (F->getAttributes().hasAttribute(AttributeSet::FunctionIndex,
209 Attribute::StackProtectStrong))
210 Strong = true;
211 else if (!F->getAttributes().hasAttribute(AttributeSet::FunctionIndex,
212 Attribute::StackProtect))
151213 return false;
152214
153215 for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
154216 BasicBlock *BB = I;
155217
156218 for (BasicBlock::iterator
157 II = BB->begin(), IE = BB->end(); II != IE; ++II)
219 II = BB->begin(), IE = BB->end(); II != IE; ++II) {
158220 if (AllocaInst *AI = dyn_cast(II)) {
159 if (AI->isArrayAllocation())
160 // This is a call to alloca with a variable size. Emit stack
161 // protectors.
221 if (AI->isArrayAllocation()) {
222 // SSP-Strong: Enable protectors for any call to alloca, regardless
223 // of size.
224 if (Strong)
225 return true;
226
227 if (const ConstantInt *CI =
228 dyn_cast(AI->getArraySize())) {
229 unsigned BufferSize = TLI->getTargetMachine().Options.SSPBufferSize;
230 if (CI->getLimitedValue(BufferSize) >= BufferSize)
231 // A call to alloca with size >= SSPBufferSize requires
232 // stack protectors.
233 return true;
234 } else // A call to alloca with a variable size requires protectors.
235 return true;
236 }
237
238 if (ContainsProtectableArray(AI->getAllocatedType(), Strong))
162239 return true;
163240
164 if (ContainsProtectableArray(AI->getAllocatedType()))
241 if (Strong && HasAddressTaken(AI)) {
242 ++NumAddrTaken;
165243 return true;
244 }
166245 }
246 }
167247 }
168248
169249 return false;
11 ; RUN: llc -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck --check-prefix=LINUX-X64 %s
22 ; RUN: llc -code-model=kernel -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck --check-prefix=LINUX-KERNEL-X64 %s
33 ; RUN: llc -mtriple=x86_64-apple-darwin < %s -o - | FileCheck --check-prefix=DARWIN-X64 %s
4 ; FIXME: Update and expand test when strong heuristic is implemented.
54
65 %struct.foo = type { [16 x i8] }
76 %struct.foo.0 = type { [4 x i8] }
7 %struct.pair = type { i32, i32 }
8 %struct.nest = type { %struct.pair, %struct.pair }
9 %struct.vec = type { <4 x i32> }
10 %class.A = type { [2 x i8] }
11 %struct.deep = type { %union.anon }
12 %union.anon = type { %struct.anon }
13 %struct.anon = type { %struct.anon.0 }
14 %struct.anon.0 = type { %union.anon.1 }
15 %union.anon.1 = type { [2 x i8] }
16 %struct.small = type { i8 }
817
918 @.str = private unnamed_addr constant [4 x i8] c"%s\0A\00", align 1
1019
576585
577586 ; test5c: no arrays / no nested arrays
578587 ; sspstrong attribute
579 ; Requires protector.
580 ; FIXME: Once strong heuristic is implemented, this should _not_ require
581 ; a protector
588 ; Requires no protector.
582589 define void @test5c(i8* %a) nounwind uwtable sspstrong {
583590 entry:
584591 ; LINUX-I386: test5c:
585 ; LINUX-I386: mov{{l|q}} %gs:
586 ; LINUX-I386: calll __stack_chk_fail
592 ; LINUX-I386-NOT: calll __stack_chk_fail
593 ; LINUX-I386: .cfi_endproc
587594
588595 ; LINUX-X64: test5c:
589 ; LINUX-X64: mov{{l|q}} %fs:
590 ; LINUX-X64: callq __stack_chk_fail
596 ; LINUX-X64-NOT: callq __stack_chk_fail
597 ; LINUX-X64: .cfi_endproc
591598
592599 ; LINUX-KERNEL-X64: test5c:
593 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
594 ; LINUX-KERNEL-X64: callq __stack_chk_fail
600 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
601 ; LINUX-KERNEL-X64: .cfi_endproc
595602
596603 ; DARWIN-X64: test5c:
597 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
598 ; DARWIN-X64: callq ___stack_chk_fail
604 ; DARWIN-X64-NOT: callq ___stack_chk_fail
605 ; DARWIN-X64: .cfi_endproc
599606 %a.addr = alloca i8*, align 8
600607 store i8* %a, i8** %a.addr, align 8
601608 %0 = load i8** %a.addr, align 8
630637 ret void
631638 }
632639
640 ; test6a: Address-of local taken (j = &a)
641 ; no ssp attribute
642 ; Requires no protector.
643 define void @test6a() nounwind uwtable {
644 entry:
645 ; LINUX-I386: test6a:
646 ; LINUX-I386-NOT: calll __stack_chk_fail
647 ; LINUX-I386: .cfi_endproc
648
649 ; LINUX-X64: test6a:
650 ; LINUX-X64-NOT: callq __stack_chk_fail
651 ; LINUX-X64: .cfi_endproc
652
653 ; LINUX-KERNEL-X64: test6a:
654 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
655 ; LINUX-KERNEL-X64: .cfi_endproc
656
657 ; DARWIN-X64: test6a:
658 ; DARWIN-X64-NOT: callq ___stack_chk_fail
659 ; DARWIN-X64: .cfi_endproc
660 %retval = alloca i32, align 4
661 %a = alloca i32, align 4
662 %j = alloca i32*, align 8
663 store i32 0, i32* %retval
664 %0 = load i32* %a, align 4
665 %add = add nsw i32 %0, 1
666 store i32 %add, i32* %a, align 4
667 store i32* %a, i32** %j, align 8
668 ret void
669 }
670
671 ; test6b: Address-of local taken (j = &a)
672 ; ssp attribute
673 ; Requires no protector.
674 define void @test6b() nounwind uwtable ssp {
675 entry:
676 ; LINUX-I386: test6b:
677 ; LINUX-I386-NOT: calll __stack_chk_fail
678 ; LINUX-I386: .cfi_endproc
679
680 ; LINUX-X64: test6b:
681 ; LINUX-X64-NOT: callq __stack_chk_fail
682 ; LINUX-X64: .cfi_endproc
683
684 ; LINUX-KERNEL-X64: test6b:
685 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
686 ; LINUX-KERNEL-X64: .cfi_endproc
687
688 ; DARWIN-X64: test6b:
689 ; DARWIN-X64-NOT: callq ___stack_chk_fail
690 ; DARWIN-X64: .cfi_endproc
691 %retval = alloca i32, align 4
692 %a = alloca i32, align 4
693 %j = alloca i32*, align 8
694 store i32 0, i32* %retval
695 %0 = load i32* %a, align 4
696 %add = add nsw i32 %0, 1
697 store i32 %add, i32* %a, align 4
698 store i32* %a, i32** %j, align 8
699 ret void
700 }
701
702 ; test6c: Address-of local taken (j = &a)
703 ; sspstrong attribute
704 ; Requires protector.
705 define void @test6c() nounwind uwtable sspstrong {
706 entry:
707 ; LINUX-I386: test6c:
708 ; LINUX-I386: mov{{l|q}} %gs:
709 ; LINUX-I386: calll __stack_chk_fail
710
711 ; LINUX-X64: test6c:
712 ; LINUX-X64: mov{{l|q}} %fs:
713 ; LINUX-X64: callq __stack_chk_fail
714
715 ; LINUX-KERNEL-X64: test6c:
716 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
717 ; LINUX-KERNEL-X64: callq __stack_chk_fail
718
719 ; DARWIN-X64: test6c:
720 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
721 ; DARWIN-X64: callq ___stack_chk_fail
722 %retval = alloca i32, align 4
723 %a = alloca i32, align 4
724 %j = alloca i32*, align 8
725 store i32 0, i32* %retval
726 %0 = load i32* %a, align 4
727 %add = add nsw i32 %0, 1
728 store i32 %add, i32* %a, align 4
729 store i32* %a, i32** %j, align 8
730 ret void
731 }
732
733 ; test6d: Address-of local taken (j = &a)
734 ; sspreq attribute
735 ; Requires protector.
736 define void @test6d() nounwind uwtable sspreq {
737 entry:
738 ; LINUX-I386: test6d:
739 ; LINUX-I386: mov{{l|q}} %gs:
740 ; LINUX-I386: calll __stack_chk_fail
741
742 ; LINUX-X64: test6d:
743 ; LINUX-X64: mov{{l|q}} %fs:
744 ; LINUX-X64: callq __stack_chk_fail
745
746 ; LINUX-KERNEL-X64: test6d:
747 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
748 ; LINUX-KERNEL-X64: callq __stack_chk_fail
749
750 ; DARWIN-X64: test6d:
751 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
752 ; DARWIN-X64: callq ___stack_chk_fail
753 %retval = alloca i32, align 4
754 %a = alloca i32, align 4
755 %j = alloca i32*, align 8
756 store i32 0, i32* %retval
757 %0 = load i32* %a, align 4
758 %add = add nsw i32 %0, 1
759 store i32 %add, i32* %a, align 4
760 store i32* %a, i32** %j, align 8
761 ret void
762 }
763
764 ; test7a: PtrToInt Cast
765 ; no ssp attribute
766 ; Requires no protector.
767 define void @test7a() nounwind uwtable readnone {
768 entry:
769 ; LINUX-I386: test7a:
770 ; LINUX-I386-NOT: calll __stack_chk_fail
771 ; LINUX-I386: .cfi_endproc
772
773 ; LINUX-X64: test7a:
774 ; LINUX-X64-NOT: callq __stack_chk_fail
775 ; LINUX-X64: .cfi_endproc
776
777 ; LINUX-KERNEL-X64: test7a:
778 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
779 ; LINUX-KERNEL-X64: .cfi_endproc
780
781 ; DARWIN-X64: test7a:
782 ; DARWIN-X64-NOT: callq ___stack_chk_fail
783 ; DARWIN-X64: .cfi_endproc
784 %a = alloca i32, align 4
785 %0 = ptrtoint i32* %a to i64
786 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0)
787 ret void
788 }
789
790 ; test7b: PtrToInt Cast
791 ; ssp attribute
792 ; Requires no protector.
793 define void @test7b() nounwind uwtable readnone ssp {
794 entry:
795 ; LINUX-I386: test7b:
796 ; LINUX-I386-NOT: calll __stack_chk_fail
797 ; LINUX-I386: .cfi_endproc
798
799 ; LINUX-X64: test7b:
800 ; LINUX-X64-NOT: callq __stack_chk_fail
801 ; LINUX-X64: .cfi_endproc
802
803 ; LINUX-KERNEL-X64: test7b:
804 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
805 ; LINUX-KERNEL-X64: .cfi_endproc
806
807 ; DARWIN-X64: test7b:
808 ; DARWIN-X64-NOT: callq ___stack_chk_fail
809 ; DARWIN-X64: .cfi_endproc
810 %a = alloca i32, align 4
811 %0 = ptrtoint i32* %a to i64
812 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0)
813 ret void
814 }
815
816 ; test7c: PtrToInt Cast
817 ; sspstrong attribute
818 ; Requires protector.
819 define void @test7c() nounwind uwtable readnone sspstrong {
820 entry:
821 ; LINUX-I386: test7c:
822 ; LINUX-I386: mov{{l|q}} %gs:
823 ; LINUX-I386: calll __stack_chk_fail
824
825 ; LINUX-X64: test7c:
826 ; LINUX-X64: mov{{l|q}} %fs:
827 ; LINUX-X64: callq __stack_chk_fail
828
829 ; LINUX-KERNEL-X64: test7c:
830 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
831 ; LINUX-KERNEL-X64: callq __stack_chk_fail
832
833 ; DARWIN-X64: test7c:
834 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
835 ; DARWIN-X64: callq ___stack_chk_fail
836 %a = alloca i32, align 4
837 %0 = ptrtoint i32* %a to i64
838 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0)
839 ret void
840 }
841
842 ; test7d: PtrToInt Cast
843 ; sspreq attribute
844 ; Requires protector.
845 define void @test7d() nounwind uwtable readnone sspreq {
846 entry:
847 ; LINUX-I386: test7d:
848 ; LINUX-I386: mov{{l|q}} %gs:
849 ; LINUX-I386: calll __stack_chk_fail
850
851 ; LINUX-X64: test7d:
852 ; LINUX-X64: mov{{l|q}} %fs:
853 ; LINUX-X64: callq __stack_chk_fail
854
855 ; LINUX-KERNEL-X64: test7d:
856 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
857 ; LINUX-KERNEL-X64: callq __stack_chk_fail
858
859 ; DARWIN-X64: test7d:
860 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
861 ; DARWIN-X64: callq ___stack_chk_fail
862 %a = alloca i32, align 4
863 %0 = ptrtoint i32* %a to i64
864 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0)
865 ret void
866 }
867
868 ; test8a: Passing addr-of to function call
869 ; no ssp attribute
870 ; Requires no protector.
871 define void @test8a() nounwind uwtable {
872 entry:
873 ; LINUX-I386: test8a:
874 ; LINUX-I386-NOT: calll __stack_chk_fail
875 ; LINUX-I386: .cfi_endproc
876
877 ; LINUX-X64: test8a:
878 ; LINUX-X64-NOT: callq __stack_chk_fail
879 ; LINUX-X64: .cfi_endproc
880
881 ; LINUX-KERNEL-X64: test8a:
882 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
883 ; LINUX-KERNEL-X64: .cfi_endproc
884
885 ; DARWIN-X64: test8a:
886 ; DARWIN-X64-NOT: callq ___stack_chk_fail
887 ; DARWIN-X64: .cfi_endproc
888 %b = alloca i32, align 4
889 call void @funcall(i32* %b) nounwind
890 ret void
891 }
892
893 ; test8b: Passing addr-of to function call
894 ; ssp attribute
895 ; Requires no protector.
896 define void @test8b() nounwind uwtable ssp {
897 entry:
898 ; LINUX-I386: test8b:
899 ; LINUX-I386-NOT: calll __stack_chk_fail
900 ; LINUX-I386: .cfi_endproc
901
902 ; LINUX-X64: test8b:
903 ; LINUX-X64-NOT: callq __stack_chk_fail
904 ; LINUX-X64: .cfi_endproc
905
906 ; LINUX-KERNEL-X64: test8b:
907 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
908 ; LINUX-KERNEL-X64: .cfi_endproc
909
910 ; DARWIN-X64: test8b:
911 ; DARWIN-X64-NOT: callq ___stack_chk_fail
912 ; DARWIN-X64: .cfi_endproc
913 %b = alloca i32, align 4
914 call void @funcall(i32* %b) nounwind
915 ret void
916 }
917
918 ; test8c: Passing addr-of to function call
919 ; sspstrong attribute
920 ; Requires protector.
921 define void @test8c() nounwind uwtable sspstrong {
922 entry:
923 ; LINUX-I386: test8c:
924 ; LINUX-I386: mov{{l|q}} %gs:
925 ; LINUX-I386: calll __stack_chk_fail
926
927 ; LINUX-X64: test8c:
928 ; LINUX-X64: mov{{l|q}} %fs:
929 ; LINUX-X64: callq __stack_chk_fail
930
931 ; LINUX-KERNEL-X64: test8c:
932 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
933 ; LINUX-KERNEL-X64: callq __stack_chk_fail
934
935 ; DARWIN-X64: test8c:
936 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
937 ; DARWIN-X64: callq ___stack_chk_fail
938 %b = alloca i32, align 4
939 call void @funcall(i32* %b) nounwind
940 ret void
941 }
942
943 ; test8d: Passing addr-of to function call
944 ; sspreq attribute
945 ; Requires protector.
946 define void @test8d() nounwind uwtable sspreq {
947 entry:
948 ; LINUX-I386: test8d:
949 ; LINUX-I386: mov{{l|q}} %gs:
950 ; LINUX-I386: calll __stack_chk_fail
951
952 ; LINUX-X64: test8d:
953 ; LINUX-X64: mov{{l|q}} %fs:
954 ; LINUX-X64: callq __stack_chk_fail
955
956 ; LINUX-KERNEL-X64: test8d:
957 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
958 ; LINUX-KERNEL-X64: callq __stack_chk_fail
959
960 ; DARWIN-X64: test8d:
961 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
962 ; DARWIN-X64: callq ___stack_chk_fail
963 %b = alloca i32, align 4
964 call void @funcall(i32* %b) nounwind
965 ret void
966 }
967
968 ; test9a: Addr-of in select instruction
969 ; no ssp attribute
970 ; Requires no protector.
971 define void @test9a() nounwind uwtable {
972 entry:
973 ; LINUX-I386: test9a:
974 ; LINUX-I386-NOT: calll __stack_chk_fail
975 ; LINUX-I386: .cfi_endproc
976
977 ; LINUX-X64: test9a:
978 ; LINUX-X64-NOT: callq __stack_chk_fail
979 ; LINUX-X64: .cfi_endproc
980
981 ; LINUX-KERNEL-X64: test9a:
982 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
983 ; LINUX-KERNEL-X64: .cfi_endproc
984
985 ; DARWIN-X64: test9a:
986 ; DARWIN-X64-NOT: callq ___stack_chk_fail
987 ; DARWIN-X64: .cfi_endproc
988 %x = alloca double, align 8
989 %call = call double @testi_aux() nounwind
990 store double %call, double* %x, align 8
991 %cmp2 = fcmp ogt double %call, 0.000000e+00
992 %y.1 = select i1 %cmp2, double* %x, double* null
993 %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), double* %y.1)
994 ret void
995 }
996
997 ; test9b: Addr-of in select instruction
998 ; ssp attribute
999 ; Requires no protector.
1000 define void @test9b() nounwind uwtable ssp {
1001 entry:
1002 ; LINUX-I386: test9b:
1003 ; LINUX-I386-NOT: calll __stack_chk_fail
1004 ; LINUX-I386: .cfi_endproc
1005
1006 ; LINUX-X64: test9b:
1007 ; LINUX-X64-NOT: callq __stack_chk_fail
1008 ; LINUX-X64: .cfi_endproc
1009
1010 ; LINUX-KERNEL-X64: test9b:
1011 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1012 ; LINUX-KERNEL-X64: .cfi_endproc
1013
1014 ; DARWIN-X64: test9b:
1015 ; DARWIN-X64-NOT: callq ___stack_chk_fail
1016 ; DARWIN-X64: .cfi_endproc
1017 %x = alloca double, align 8
1018 %call = call double @testi_aux() nounwind
1019 store double %call, double* %x, align 8
1020 %cmp2 = fcmp ogt double %call, 0.000000e+00
1021 %y.1 = select i1 %cmp2, double* %x, double* null
1022 %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), double* %y.1)
1023 ret void
1024 }
1025
1026 ; test9c: Addr-of in select instruction
1027 ; sspstrong attribute
1028 ; Requires protector.
1029 define void @test9c() nounwind uwtable sspstrong {
1030 entry:
1031 ; LINUX-I386: test9c:
1032 ; LINUX-I386: mov{{l|q}} %gs:
1033 ; LINUX-I386: calll __stack_chk_fail
1034
1035 ; LINUX-X64: test9c:
1036 ; LINUX-X64: mov{{l|q}} %fs:
1037 ; LINUX-X64: callq __stack_chk_fail
1038
1039 ; LINUX-KERNEL-X64: test9c:
1040 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1041 ; LINUX-KERNEL-X64: callq __stack_chk_fail
1042
1043 ; DARWIN-X64: test9c:
1044 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1045 ; DARWIN-X64: callq ___stack_chk_fail
1046 %x = alloca double, align 8
1047 %call = call double @testi_aux() nounwind
1048 store double %call, double* %x, align 8
1049 %cmp2 = fcmp ogt double %call, 0.000000e+00
1050 %y.1 = select i1 %cmp2, double* %x, double* null
1051 %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), double* %y.1)
1052 ret void
1053 }
1054
1055 ; test9d: Addr-of in select instruction
1056 ; sspreq attribute
1057 ; Requires protector.
1058 define void @test9d() nounwind uwtable sspreq {
1059 entry:
1060 ; LINUX-I386: test9d:
1061 ; LINUX-I386: mov{{l|q}} %gs:
1062 ; LINUX-I386: calll __stack_chk_fail
1063
1064 ; LINUX-X64: test9d:
1065 ; LINUX-X64: mov{{l|q}} %fs:
1066 ; LINUX-X64: callq __stack_chk_fail
1067
1068 ; LINUX-KERNEL-X64: test9d:
1069 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1070 ; LINUX-KERNEL-X64: callq __stack_chk_fail
1071
1072 ; DARWIN-X64: test9d:
1073 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1074 ; DARWIN-X64: callq ___stack_chk_fail
1075 %x = alloca double, align 8
1076 %call = call double @testi_aux() nounwind
1077 store double %call, double* %x, align 8
1078 %cmp2 = fcmp ogt double %call, 0.000000e+00
1079 %y.1 = select i1 %cmp2, double* %x, double* null
1080 %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), double* %y.1)
1081 ret void
1082 }
1083
1084 ; test10a: Addr-of in phi instruction
1085 ; no ssp attribute
1086 ; Requires no protector.
1087 define void @test10a() nounwind uwtable {
1088 entry:
1089 ; LINUX-I386: test10a:
1090 ; LINUX-I386-NOT: calll __stack_chk_fail
1091 ; LINUX-I386: .cfi_endproc
1092
1093 ; LINUX-X64: test10a:
1094 ; LINUX-X64-NOT: callq __stack_chk_fail
1095 ; LINUX-X64: .cfi_endproc
1096
1097 ; LINUX-KERNEL-X64: test10a:
1098 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1099 ; LINUX-KERNEL-X64: .cfi_endproc
1100
1101 ; DARWIN-X64: test10a:
1102 ; DARWIN-X64-NOT: callq ___stack_chk_fail
1103 ; DARWIN-X64: .cfi_endproc
1104 %x = alloca double, align 8
1105 %call = call double @testi_aux() nounwind
1106 store double %call, double* %x, align 8
1107 %cmp = fcmp ogt double %call, 3.140000e+00
1108 br i1 %cmp, label %if.then, label %if.else
1109
1110 if.then: ; preds = %entry
1111 %call1 = call double @testi_aux() nounwind
1112 store double %call1, double* %x, align 8
1113 br label %if.end4
1114
1115 if.else: ; preds = %entry
1116 %cmp2 = fcmp ogt double %call, 1.000000e+00
1117 br i1 %cmp2, label %if.then3, label %if.end4
1118
1119 if.then3: ; preds = %if.else
1120 br label %if.end4
1121
1122 if.end4: ; preds = %if.else, %if.then3, %if.then
1123 %y.0 = phi double* [ null, %if.then ], [ %x, %if.then3 ], [ null, %if.else ]
1124 %call5 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), double* %y.0) nounwind
1125 ret void
1126 }
1127
1128 ; test10b: Addr-of in phi instruction
1129 ; ssp attribute
1130 ; Requires no protector.
1131 define void @test10b() nounwind uwtable ssp {
1132 entry:
1133 ; LINUX-I386: test10b:
1134 ; LINUX-I386-NOT: calll __stack_chk_fail
1135 ; LINUX-I386: .cfi_endproc
1136
1137 ; LINUX-X64: test10b:
1138 ; LINUX-X64-NOT: callq __stack_chk_fail
1139 ; LINUX-X64: .cfi_endproc
1140
1141 ; LINUX-KERNEL-X64: test10b:
1142 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1143 ; LINUX-KERNEL-X64: .cfi_endproc
1144
1145 ; DARWIN-X64: test10b:
1146 ; DARWIN-X64-NOT: callq ___stack_chk_fail
1147 ; DARWIN-X64: .cfi_endproc
1148 %x = alloca double, align 8
1149 %call = call double @testi_aux() nounwind
1150 store double %call, double* %x, align 8
1151 %cmp = fcmp ogt double %call, 3.140000e+00
1152 br i1 %cmp, label %if.then, label %if.else
1153
1154 if.then: ; preds = %entry
1155 %call1 = call double @testi_aux() nounwind
1156 store double %call1, double* %x, align 8
1157 br label %if.end4
1158
1159 if.else: ; preds = %entry
1160 %cmp2 = fcmp ogt double %call, 1.000000e+00
1161 br i1 %cmp2, label %if.then3, label %if.end4
1162
1163 if.then3: ; preds = %if.else
1164 br label %if.end4
1165
1166 if.end4: ; preds = %if.else, %if.then3, %if.then
1167 %y.0 = phi double* [ null, %if.then ], [ %x, %if.then3 ], [ null, %if.else ]
1168 %call5 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), double* %y.0) nounwind
1169 ret void
1170 }
1171
1172 ; test10c: Addr-of in phi instruction
1173 ; sspstrong attribute
1174 ; Requires protector.
1175 define void @test10c() nounwind uwtable sspstrong {
1176 entry:
1177 ; LINUX-I386: test10c:
1178 ; LINUX-I386: mov{{l|q}} %gs:
1179 ; LINUX-I386: calll __stack_chk_fail
1180
1181 ; LINUX-X64: test10c:
1182 ; LINUX-X64: mov{{l|q}} %fs:
1183 ; LINUX-X64: callq __stack_chk_fail
1184
1185 ; LINUX-KERNEL-X64: test10c:
1186 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1187 ; LINUX-KERNEL-X64: callq __stack_chk_fail
1188
1189 ; DARWIN-X64: test10c:
1190 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1191 ; DARWIN-X64: callq ___stack_chk_fail
1192 %x = alloca double, align 8
1193 %call = call double @testi_aux() nounwind
1194 store double %call, double* %x, align 8
1195 %cmp = fcmp ogt double %call, 3.140000e+00
1196 br i1 %cmp, label %if.then, label %if.else
1197
1198 if.then: ; preds = %entry
1199 %call1 = call double @testi_aux() nounwind
1200 store double %call1, double* %x, align 8
1201 br label %if.end4
1202
1203 if.else: ; preds = %entry
1204 %cmp2 = fcmp ogt double %call, 1.000000e+00
1205 br i1 %cmp2, label %if.then3, label %if.end4
1206
1207 if.then3: ; preds = %if.else
1208 br label %if.end4
1209
1210 if.end4: ; preds = %if.else, %if.then3, %if.then
1211 %y.0 = phi double* [ null, %if.then ], [ %x, %if.then3 ], [ null, %if.else ]
1212 %call5 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), double* %y.0) nounwind
1213 ret void
1214 }
1215
1216 ; test10d: Addr-of in phi instruction
1217 ; sspreq attribute
1218 ; Requires protector.
1219 define void @test10d() nounwind uwtable sspreq {
1220 entry:
1221 ; LINUX-I386: test10d:
1222 ; LINUX-I386: mov{{l|q}} %gs:
1223 ; LINUX-I386: calll __stack_chk_fail
1224
1225 ; LINUX-X64: test10d:
1226 ; LINUX-X64: mov{{l|q}} %fs:
1227 ; LINUX-X64: callq __stack_chk_fail
1228
1229 ; LINUX-KERNEL-X64: test10d:
1230 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1231 ; LINUX-KERNEL-X64: callq __stack_chk_fail
1232
1233 ; DARWIN-X64: test10d:
1234 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1235 ; DARWIN-X64: callq ___stack_chk_fail
1236 %x = alloca double, align 8
1237 %call = call double @testi_aux() nounwind
1238 store double %call, double* %x, align 8
1239 %cmp = fcmp ogt double %call, 3.140000e+00
1240 br i1 %cmp, label %if.then, label %if.else
1241
1242 if.then: ; preds = %entry
1243 %call1 = call double @testi_aux() nounwind
1244 store double %call1, double* %x, align 8
1245 br label %if.end4
1246
1247 if.else: ; preds = %entry
1248 %cmp2 = fcmp ogt double %call, 1.000000e+00
1249 br i1 %cmp2, label %if.then3, label %if.end4
1250
1251 if.then3: ; preds = %if.else
1252 br label %if.end4
1253
1254 if.end4: ; preds = %if.else, %if.then3, %if.then
1255 %y.0 = phi double* [ null, %if.then ], [ %x, %if.then3 ], [ null, %if.else ]
1256 %call5 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), double* %y.0) nounwind
1257 ret void
1258 }
1259
1260 ; test11a: Addr-of struct element. (GEP followed by store).
1261 ; no ssp attribute
1262 ; Requires no protector.
1263 define void @test11a() nounwind uwtable {
1264 entry:
1265 ; LINUX-I386: test11a:
1266 ; LINUX-I386-NOT: calll __stack_chk_fail
1267 ; LINUX-I386: .cfi_endproc
1268
1269 ; LINUX-X64: test11a:
1270 ; LINUX-X64-NOT: callq __stack_chk_fail
1271 ; LINUX-X64: .cfi_endproc
1272
1273 ; LINUX-KERNEL-X64: test11a:
1274 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1275 ; LINUX-KERNEL-X64: .cfi_endproc
1276
1277 ; DARWIN-X64: test11a:
1278 ; DARWIN-X64-NOT: callq ___stack_chk_fail
1279 ; DARWIN-X64: .cfi_endproc
1280 %c = alloca %struct.pair, align 4
1281 %b = alloca i32*, align 8
1282 %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1
1283 store i32* %y, i32** %b, align 8
1284 %0 = load i32** %b, align 8
1285 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32* %0)
1286 ret void
1287 }
1288
1289 ; test11b: Addr-of struct element. (GEP followed by store).
1290 ; ssp attribute
1291 ; Requires no protector.
1292 define void @test11b() nounwind uwtable ssp {
1293 entry:
1294 ; LINUX-I386: test11b:
1295 ; LINUX-I386-NOT: calll __stack_chk_fail
1296 ; LINUX-I386: .cfi_endproc
1297
1298 ; LINUX-X64: test11b:
1299 ; LINUX-X64-NOT: callq __stack_chk_fail
1300 ; LINUX-X64: .cfi_endproc
1301
1302 ; LINUX-KERNEL-X64: test11b:
1303 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1304 ; LINUX-KERNEL-X64: .cfi_endproc
1305
1306 ; DARWIN-X64: test11b:
1307 ; DARWIN-X64-NOT: callq ___stack_chk_fail
1308 ; DARWIN-X64: .cfi_endproc
1309 %c = alloca %struct.pair, align 4
1310 %b = alloca i32*, align 8
1311 %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1
1312 store i32* %y, i32** %b, align 8
1313 %0 = load i32** %b, align 8
1314 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32* %0)
1315 ret void
1316 }
1317
1318 ; test11c: Addr-of struct element. (GEP followed by store).
1319 ; sspstrong attribute
1320 ; Requires protector.
1321 define void @test11c() nounwind uwtable sspstrong {
1322 entry:
1323 ; LINUX-I386: test11c:
1324 ; LINUX-I386: mov{{l|q}} %gs:
1325 ; LINUX-I386: calll __stack_chk_fail
1326
1327 ; LINUX-X64: test11c:
1328 ; LINUX-X64: mov{{l|q}} %fs:
1329 ; LINUX-X64: callq __stack_chk_fail
1330
1331 ; LINUX-KERNEL-X64: test11c:
1332 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1333 ; LINUX-KERNEL-X64: callq __stack_chk_fail
1334
1335 ; DARWIN-X64: test11c:
1336 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1337 ; DARWIN-X64: callq ___stack_chk_fail
1338 %c = alloca %struct.pair, align 4
1339 %b = alloca i32*, align 8
1340 %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1
1341 store i32* %y, i32** %b, align 8
1342 %0 = load i32** %b, align 8
1343 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32* %0)
1344 ret void
1345 }
1346
1347 ; test11d: Addr-of struct element. (GEP followed by store).
1348 ; sspreq attribute
1349 ; Requires protector.
1350 define void @test11d() nounwind uwtable sspreq {
1351 entry:
1352 ; LINUX-I386: test11d:
1353 ; LINUX-I386: mov{{l|q}} %gs:
1354 ; LINUX-I386: calll __stack_chk_fail
1355
1356 ; LINUX-X64: test11d:
1357 ; LINUX-X64: mov{{l|q}} %fs:
1358 ; LINUX-X64: callq __stack_chk_fail
1359
1360 ; LINUX-KERNEL-X64: test11d:
1361 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1362 ; LINUX-KERNEL-X64: callq __stack_chk_fail
1363
1364 ; DARWIN-X64: test11d:
1365 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1366 ; DARWIN-X64: callq ___stack_chk_fail
1367 %c = alloca %struct.pair, align 4
1368 %b = alloca i32*, align 8
1369 %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1
1370 store i32* %y, i32** %b, align 8
1371 %0 = load i32** %b, align 8
1372 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32* %0)
1373 ret void
1374 }
1375
1376 ; test12a: Addr-of struct element, GEP followed by ptrtoint.
1377 ; no ssp attribute
1378 ; Requires no protector.
1379 define void @test12a() nounwind uwtable {
1380 entry:
1381 ; LINUX-I386: test12a:
1382 ; LINUX-I386-NOT: calll __stack_chk_fail
1383 ; LINUX-I386: .cfi_endproc
1384
1385 ; LINUX-X64: test12a:
1386 ; LINUX-X64-NOT: callq __stack_chk_fail
1387 ; LINUX-X64: .cfi_endproc
1388
1389 ; LINUX-KERNEL-X64: test12a:
1390 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1391 ; LINUX-KERNEL-X64: .cfi_endproc
1392
1393 ; DARWIN-X64: test12a:
1394 ; DARWIN-X64-NOT: callq ___stack_chk_fail
1395 ; DARWIN-X64: .cfi_endproc
1396 %c = alloca %struct.pair, align 4
1397 %b = alloca i32*, align 8
1398 %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1
1399 %0 = ptrtoint i32* %y to i64
1400 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0)
1401 ret void
1402 }
1403
1404 ; test12b: Addr-of struct element, GEP followed by ptrtoint.
1405 ; ssp attribute
1406 ; Requires no protector.
1407 define void @test12b() nounwind uwtable ssp {
1408 entry:
1409 ; LINUX-I386: test12b:
1410 ; LINUX-I386-NOT: calll __stack_chk_fail
1411 ; LINUX-I386: .cfi_endproc
1412
1413 ; LINUX-X64: test12b:
1414 ; LINUX-X64-NOT: callq __stack_chk_fail
1415 ; LINUX-X64: .cfi_endproc
1416
1417 ; LINUX-KERNEL-X64: test12b:
1418 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1419 ; LINUX-KERNEL-X64: .cfi_endproc
1420
1421 ; DARWIN-X64: test12b:
1422 ; DARWIN-X64-NOT: callq ___stack_chk_fail
1423 ; DARWIN-X64: .cfi_endproc
1424 %c = alloca %struct.pair, align 4
1425 %b = alloca i32*, align 8
1426 %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1
1427 %0 = ptrtoint i32* %y to i64
1428 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0)
1429 ret void
1430 }
1431
1432 ; test12c: Addr-of struct element, GEP followed by ptrtoint.
1433 ; sspstrong attribute
1434 ; Requires protector.
1435 define void @test12c() nounwind uwtable sspstrong {
1436 entry:
1437 ; LINUX-I386: test12c:
1438 ; LINUX-I386: mov{{l|q}} %gs:
1439 ; LINUX-I386: calll __stack_chk_fail
1440
1441 ; LINUX-X64: test12c:
1442 ; LINUX-X64: mov{{l|q}} %fs:
1443 ; LINUX-X64: callq __stack_chk_fail
1444
1445 ; LINUX-KERNEL-X64: test12c:
1446 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1447 ; LINUX-KERNEL-X64: callq __stack_chk_fail
1448
1449 ; DARWIN-X64: test12c:
1450 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1451 ; DARWIN-X64: callq ___stack_chk_fail
1452 %c = alloca %struct.pair, align 4
1453 %b = alloca i32*, align 8
1454 %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1
1455 %0 = ptrtoint i32* %y to i64
1456 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0)
1457 ret void
1458 }
1459
1460 ; test12d: Addr-of struct element, GEP followed by ptrtoint.
1461 ; sspreq attribute
1462 ; Requires protector.
1463 define void @test12d() nounwind uwtable sspreq {
1464 entry:
1465 ; LINUX-I386: test12d:
1466 ; LINUX-I386: mov{{l|q}} %gs:
1467 ; LINUX-I386: calll __stack_chk_fail
1468
1469 ; LINUX-X64: test12d:
1470 ; LINUX-X64: mov{{l|q}} %fs:
1471 ; LINUX-X64: callq __stack_chk_fail
1472
1473 ; LINUX-KERNEL-X64: test12d:
1474 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1475 ; LINUX-KERNEL-X64: callq __stack_chk_fail
1476
1477 ; DARWIN-X64: test12d:
1478 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1479 ; DARWIN-X64: callq ___stack_chk_fail
1480 %c = alloca %struct.pair, align 4
1481 %b = alloca i32*, align 8
1482 %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1
1483 %0 = ptrtoint i32* %y to i64
1484 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0)
1485 ret void
1486 }
1487
1488 ; test13a: Addr-of struct element, GEP followed by callinst.
1489 ; no ssp attribute
1490 ; Requires no protector.
1491 define void @test13a() nounwind uwtable {
1492 entry:
1493 ; LINUX-I386: test13a:
1494 ; LINUX-I386-NOT: calll __stack_chk_fail
1495 ; LINUX-I386: .cfi_endproc
1496
1497 ; LINUX-X64: test13a:
1498 ; LINUX-X64-NOT: callq __stack_chk_fail
1499 ; LINUX-X64: .cfi_endproc
1500
1501 ; LINUX-KERNEL-X64: test13a:
1502 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1503 ; LINUX-KERNEL-X64: .cfi_endproc
1504
1505 ; DARWIN-X64: test13a:
1506 ; DARWIN-X64-NOT: callq ___stack_chk_fail
1507 ; DARWIN-X64: .cfi_endproc
1508 %c = alloca %struct.pair, align 4
1509 %y = getelementptr inbounds %struct.pair* %c, i64 0, i32 1
1510 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %y) nounwind
1511 ret void
1512 }
1513
1514 ; test13b: Addr-of struct element, GEP followed by callinst.
1515 ; ssp attribute
1516 ; Requires no protector.
1517 define void @test13b() nounwind uwtable ssp {
1518 entry:
1519 ; LINUX-I386: test13b:
1520 ; LINUX-I386-NOT: calll __stack_chk_fail
1521 ; LINUX-I386: .cfi_endproc
1522
1523 ; LINUX-X64: test13b:
1524 ; LINUX-X64-NOT: callq __stack_chk_fail
1525 ; LINUX-X64: .cfi_endproc
1526
1527 ; LINUX-KERNEL-X64: test13b:
1528 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1529 ; LINUX-KERNEL-X64: .cfi_endproc
1530
1531 ; DARWIN-X64: test13b:
1532 ; DARWIN-X64-NOT: callq ___stack_chk_fail
1533 ; DARWIN-X64: .cfi_endproc
1534 %c = alloca %struct.pair, align 4
1535 %y = getelementptr inbounds %struct.pair* %c, i64 0, i32 1
1536 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %y) nounwind
1537 ret void
1538 }
1539
1540 ; test13c: Addr-of struct element, GEP followed by callinst.
1541 ; sspstrong attribute
1542 ; Requires protector.
1543 define void @test13c() nounwind uwtable sspstrong {
1544 entry:
1545 ; LINUX-I386: test13c:
1546 ; LINUX-I386: mov{{l|q}} %gs:
1547 ; LINUX-I386: calll __stack_chk_fail
1548
1549 ; LINUX-X64: test13c:
1550 ; LINUX-X64: mov{{l|q}} %fs:
1551 ; LINUX-X64: callq __stack_chk_fail
1552
1553 ; LINUX-KERNEL-X64: test13c:
1554 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1555 ; LINUX-KERNEL-X64: callq __stack_chk_fail
1556
1557 ; DARWIN-X64: test13c:
1558 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1559 ; DARWIN-X64: callq ___stack_chk_fail
1560 %c = alloca %struct.pair, align 4
1561 %y = getelementptr inbounds %struct.pair* %c, i64 0, i32 1
1562 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %y) nounwind
1563 ret void
1564 }
1565
1566 ; test13d: Addr-of struct element, GEP followed by callinst.
1567 ; sspreq attribute
1568 ; Requires protector.
1569 define void @test13d() nounwind uwtable sspreq {
1570 entry:
1571 ; LINUX-I386: test13d:
1572 ; LINUX-I386: mov{{l|q}} %gs:
1573 ; LINUX-I386: calll __stack_chk_fail
1574
1575 ; LINUX-X64: test13d:
1576 ; LINUX-X64: mov{{l|q}} %fs:
1577 ; LINUX-X64: callq __stack_chk_fail
1578
1579 ; LINUX-KERNEL-X64: test13d:
1580 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1581 ; LINUX-KERNEL-X64: callq __stack_chk_fail
1582
1583 ; DARWIN-X64: test13d:
1584 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1585 ; DARWIN-X64: callq ___stack_chk_fail
1586 %c = alloca %struct.pair, align 4
1587 %y = getelementptr inbounds %struct.pair* %c, i64 0, i32 1
1588 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %y) nounwind
1589 ret void
1590 }
1591
1592 ; test14a: Addr-of a local, optimized into a GEP (e.g., &a - 12)
1593 ; no ssp attribute
1594 ; Requires no protector.
1595 define void @test14a() nounwind uwtable {
1596 entry:
1597 ; LINUX-I386: test14a:
1598 ; LINUX-I386-NOT: calll __stack_chk_fail
1599 ; LINUX-I386: .cfi_endproc
1600
1601 ; LINUX-X64: test14a:
1602 ; LINUX-X64-NOT: callq __stack_chk_fail
1603 ; LINUX-X64: .cfi_endproc
1604
1605 ; LINUX-KERNEL-X64: test14a:
1606 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1607 ; LINUX-KERNEL-X64: .cfi_endproc
1608
1609 ; DARWIN-X64: test14a:
1610 ; DARWIN-X64-NOT: callq ___stack_chk_fail
1611 ; DARWIN-X64: .cfi_endproc
1612 %a = alloca i32, align 4
1613 %add.ptr5 = getelementptr inbounds i32* %a, i64 -12
1614 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %add.ptr5) nounwind
1615 ret void
1616 }
1617
1618 ; test14b: Addr-of a local, optimized into a GEP (e.g., &a - 12)
1619 ; ssp attribute
1620 ; Requires no protector.
1621 define void @test14b() nounwind uwtable ssp {
1622 entry:
1623 ; LINUX-I386: test14b:
1624 ; LINUX-I386-NOT: calll __stack_chk_fail
1625 ; LINUX-I386: .cfi_endproc
1626
1627 ; LINUX-X64: test14b:
1628 ; LINUX-X64-NOT: callq __stack_chk_fail
1629 ; LINUX-X64: .cfi_endproc
1630
1631 ; LINUX-KERNEL-X64: test14b:
1632 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1633 ; LINUX-KERNEL-X64: .cfi_endproc
1634
1635 ; DARWIN-X64: test14b:
1636 ; DARWIN-X64-NOT: callq ___stack_chk_fail
1637 ; DARWIN-X64: .cfi_endproc
1638 %a = alloca i32, align 4
1639 %add.ptr5 = getelementptr inbounds i32* %a, i64 -12
1640 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %add.ptr5) nounwind
1641 ret void
1642 }
1643
1644 ; test14c: Addr-of a local, optimized into a GEP (e.g., &a - 12)
1645 ; sspstrong attribute
1646 ; Requires protector.
1647 define void @test14c() nounwind uwtable sspstrong {
1648 entry:
1649 ; LINUX-I386: test14c:
1650 ; LINUX-I386: mov{{l|q}} %gs:
1651 ; LINUX-I386: calll __stack_chk_fail
1652
1653 ; LINUX-X64: test14c:
1654 ; LINUX-X64: mov{{l|q}} %fs:
1655 ; LINUX-X64: callq __stack_chk_fail
1656
1657 ; LINUX-KERNEL-X64: test14c:
1658 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1659 ; LINUX-KERNEL-X64: callq __stack_chk_fail
1660
1661 ; DARWIN-X64: test14c:
1662 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1663 ; DARWIN-X64: callq ___stack_chk_fail
1664 %a = alloca i32, align 4
1665 %add.ptr5 = getelementptr inbounds i32* %a, i64 -12
1666 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %add.ptr5) nounwind
1667 ret void
1668 }
1669
1670 ; test14d: Addr-of a local, optimized into a GEP (e.g., &a - 12)
1671 ; sspreq attribute
1672 ; Requires protector.
1673 define void @test14d() nounwind uwtable sspreq {
1674 entry:
1675 ; LINUX-I386: test14d:
1676 ; LINUX-I386: mov{{l|q}} %gs:
1677 ; LINUX-I386: calll __stack_chk_fail
1678
1679 ; LINUX-X64: test14d:
1680 ; LINUX-X64: mov{{l|q}} %fs:
1681 ; LINUX-X64: callq __stack_chk_fail
1682
1683 ; LINUX-KERNEL-X64: test14d:
1684 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1685 ; LINUX-KERNEL-X64: callq __stack_chk_fail
1686
1687 ; DARWIN-X64: test14d:
1688 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1689 ; DARWIN-X64: callq ___stack_chk_fail
1690 %a = alloca i32, align 4
1691 %add.ptr5 = getelementptr inbounds i32* %a, i64 -12
1692 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %add.ptr5) nounwind
1693 ret void
1694 }
1695
1696 ; test15a: Addr-of a local cast to a ptr of a different type
1697 ; (e.g., int a; ... ; float *b = &a;)
1698 ; no ssp attribute
1699 ; Requires no protector.
1700 define void @test15a() nounwind uwtable {
1701 entry:
1702 ; LINUX-I386: test15a:
1703 ; LINUX-I386-NOT: calll __stack_chk_fail
1704 ; LINUX-I386: .cfi_endproc
1705
1706 ; LINUX-X64: test15a:
1707 ; LINUX-X64-NOT: callq __stack_chk_fail
1708 ; LINUX-X64: .cfi_endproc
1709
1710 ; LINUX-KERNEL-X64: test15a:
1711 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1712 ; LINUX-KERNEL-X64: .cfi_endproc
1713
1714 ; DARWIN-X64: test15a:
1715 ; DARWIN-X64-NOT: callq ___stack_chk_fail
1716 ; DARWIN-X64: .cfi_endproc
1717 %a = alloca i32, align 4
1718 %b = alloca float*, align 8
1719 store i32 0, i32* %a, align 4
1720 %0 = bitcast i32* %a to float*
1721 store float* %0, float** %b, align 8
1722 %1 = load float** %b, align 8
1723 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), float* %1)
1724 ret void
1725 }
1726
1727 ; test15b: Addr-of a local cast to a ptr of a different type
1728 ; (e.g., int a; ... ; float *b = &a;)
1729 ; ssp attribute
1730 ; Requires no protector.
1731 define void @test15b() nounwind uwtable ssp {
1732 entry:
1733 ; LINUX-I386: test15b:
1734 ; LINUX-I386-NOT: calll __stack_chk_fail
1735 ; LINUX-I386: .cfi_endproc
1736
1737 ; LINUX-X64: test15b:
1738 ; LINUX-X64-NOT: callq __stack_chk_fail
1739 ; LINUX-X64: .cfi_endproc
1740
1741 ; LINUX-KERNEL-X64: test15b:
1742 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1743 ; LINUX-KERNEL-X64: .cfi_endproc
1744
1745 ; DARWIN-X64: test15b:
1746 ; DARWIN-X64-NOT: callq ___stack_chk_fail
1747 ; DARWIN-X64: .cfi_endproc
1748 %a = alloca i32, align 4
1749 %b = alloca float*, align 8
1750 store i32 0, i32* %a, align 4
1751 %0 = bitcast i32* %a to float*
1752 store float* %0, float** %b, align 8
1753 %1 = load float** %b, align 8
1754 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), float* %1)
1755 ret void
1756 }
1757
1758 ; test15c: Addr-of a local cast to a ptr of a different type
1759 ; (e.g., int a; ... ; float *b = &a;)
1760 ; sspstrong attribute
1761 ; Requires protector.
1762 define void @test15c() nounwind uwtable sspstrong {
1763 entry:
1764 ; LINUX-I386: test15c:
1765 ; LINUX-I386: mov{{l|q}} %gs:
1766 ; LINUX-I386: calll __stack_chk_fail
1767
1768 ; LINUX-X64: test15c:
1769 ; LINUX-X64: mov{{l|q}} %fs:
1770 ; LINUX-X64: callq __stack_chk_fail
1771
1772 ; LINUX-KERNEL-X64: test15c:
1773 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1774 ; LINUX-KERNEL-X64: callq __stack_chk_fail
1775
1776 ; DARWIN-X64: test15c:
1777 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1778 ; DARWIN-X64: callq ___stack_chk_fail
1779 %a = alloca i32, align 4
1780 %b = alloca float*, align 8
1781 store i32 0, i32* %a, align 4
1782 %0 = bitcast i32* %a to float*
1783 store float* %0, float** %b, align 8
1784 %1 = load float** %b, align 8
1785 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), float* %1)
1786 ret void
1787 }
1788
1789 ; test15d: Addr-of a local cast to a ptr of a different type
1790 ; (e.g., int a; ... ; float *b = &a;)
1791 ; sspreq attribute
1792 ; Requires protector.
1793 define void @test15d() nounwind uwtable sspreq {
1794 entry:
1795 ; LINUX-I386: test15d:
1796 ; LINUX-I386: mov{{l|q}} %gs:
1797 ; LINUX-I386: calll __stack_chk_fail
1798
1799 ; LINUX-X64: test15d:
1800 ; LINUX-X64: mov{{l|q}} %fs:
1801 ; LINUX-X64: callq __stack_chk_fail
1802
1803 ; LINUX-KERNEL-X64: test15d:
1804 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1805 ; LINUX-KERNEL-X64: callq __stack_chk_fail
1806
1807 ; DARWIN-X64: test15d:
1808 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1809 ; DARWIN-X64: callq ___stack_chk_fail
1810 %a = alloca i32, align 4
1811 %b = alloca float*, align 8
1812 store i32 0, i32* %a, align 4
1813 %0 = bitcast i32* %a to float*
1814 store float* %0, float** %b, align 8
1815 %1 = load float** %b, align 8
1816 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), float* %1)
1817 ret void
1818 }
1819
1820 ; test16a: Addr-of a local cast to a ptr of a different type (optimized)
1821 ; (e.g., int a; ... ; float *b = &a;)
1822 ; no ssp attribute
1823 ; Requires no protector.
1824 define void @test16a() nounwind uwtable {
1825 entry:
1826 ; LINUX-I386: test16a:
1827 ; LINUX-I386-NOT: calll __stack_chk_fail
1828 ; LINUX-I386: .cfi_endproc
1829
1830 ; LINUX-X64: test16a:
1831 ; LINUX-X64-NOT: callq __stack_chk_fail
1832 ; LINUX-X64: .cfi_endproc
1833
1834 ; LINUX-KERNEL-X64: test16a:
1835 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1836 ; LINUX-KERNEL-X64: .cfi_endproc
1837
1838 ; DARWIN-X64: test16a:
1839 ; DARWIN-X64-NOT: callq ___stack_chk_fail
1840 ; DARWIN-X64: .cfi_endproc
1841 %a = alloca i32, align 4
1842 store i32 0, i32* %a, align 4
1843 %0 = bitcast i32* %a to float*
1844 call void @funfloat(float* %0) nounwind
1845 ret void
1846 }
1847
1848 ; test16b: Addr-of a local cast to a ptr of a different type (optimized)
1849 ; (e.g., int a; ... ; float *b = &a;)
1850 ; ssp attribute
1851 ; Requires no protector.
1852 define void @test16b() nounwind uwtable ssp {
1853 entry:
1854 ; LINUX-I386: test16b:
1855 ; LINUX-I386-NOT: calll __stack_chk_fail
1856 ; LINUX-I386: .cfi_endproc
1857
1858 ; LINUX-X64: test16b:
1859 ; LINUX-X64-NOT: callq __stack_chk_fail
1860 ; LINUX-X64: .cfi_endproc
1861
1862 ; LINUX-KERNEL-X64: test16b:
1863 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1864 ; LINUX-KERNEL-X64: .cfi_endproc
1865
1866 ; DARWIN-X64: test16b:
1867 ; DARWIN-X64-NOT: callq ___stack_chk_fail
1868 ; DARWIN-X64: .cfi_endproc
1869 %a = alloca i32, align 4
1870 store i32 0, i32* %a, align 4
1871 %0 = bitcast i32* %a to float*
1872 call void @funfloat(float* %0) nounwind
1873 ret void
1874 }
1875
1876 ; test16c: Addr-of a local cast to a ptr of a different type (optimized)
1877 ; (e.g., int a; ... ; float *b = &a;)
1878 ; sspstrong attribute
1879 ; Requires protector.
1880 define void @test16c() nounwind uwtable sspstrong {
1881 entry:
1882 ; LINUX-I386: test16c:
1883 ; LINUX-I386: mov{{l|q}} %gs:
1884 ; LINUX-I386: calll __stack_chk_fail
1885
1886 ; LINUX-X64: test16c:
1887 ; LINUX-X64: mov{{l|q}} %fs:
1888 ; LINUX-X64: callq __stack_chk_fail
1889
1890 ; LINUX-KERNEL-X64: test16c:
1891 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1892 ; LINUX-KERNEL-X64: callq __stack_chk_fail
1893
1894 ; DARWIN-X64: test16c:
1895 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1896 ; DARWIN-X64: callq ___stack_chk_fail
1897 %a = alloca i32, align 4
1898 store i32 0, i32* %a, align 4
1899 %0 = bitcast i32* %a to float*
1900 call void @funfloat(float* %0) nounwind
1901 ret void
1902 }
1903
1904 ; test16d: Addr-of a local cast to a ptr of a different type (optimized)
1905 ; (e.g., int a; ... ; float *b = &a;)
1906 ; sspreq attribute
1907 ; Requires protector.
1908 define void @test16d() nounwind uwtable sspreq {
1909 entry:
1910 ; LINUX-I386: test16d:
1911 ; LINUX-I386: mov{{l|q}} %gs:
1912 ; LINUX-I386: calll __stack_chk_fail
1913
1914 ; LINUX-X64: test16d:
1915 ; LINUX-X64: mov{{l|q}} %fs:
1916 ; LINUX-X64: callq __stack_chk_fail
1917
1918 ; LINUX-KERNEL-X64: test16d:
1919 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1920 ; LINUX-KERNEL-X64: callq __stack_chk_fail
1921
1922 ; DARWIN-X64: test16d:
1923 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1924 ; DARWIN-X64: callq ___stack_chk_fail
1925 %a = alloca i32, align 4
1926 store i32 0, i32* %a, align 4
1927 %0 = bitcast i32* %a to float*
1928 call void @funfloat(float* %0) nounwind
1929 ret void
1930 }
1931
1932 ; test17a: Addr-of a vector nested in a struct
1933 ; no ssp attribute
1934 ; Requires no protector.
1935 define void @test17a() nounwind uwtable {
1936 entry:
1937 ; LINUX-I386: test17a:
1938 ; LINUX-I386-NOT: calll __stack_chk_fail
1939 ; LINUX-I386: .cfi_endproc
1940
1941 ; LINUX-X64: test17a:
1942 ; LINUX-X64-NOT: callq __stack_chk_fail
1943 ; LINUX-X64: .cfi_endproc
1944
1945 ; LINUX-KERNEL-X64: test17a:
1946 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1947 ; LINUX-KERNEL-X64: .cfi_endproc
1948
1949 ; DARWIN-X64: test17a:
1950 ; DARWIN-X64-NOT: callq ___stack_chk_fail
1951 ; DARWIN-X64: .cfi_endproc
1952 %c = alloca %struct.vec, align 16
1953 %y = getelementptr inbounds %struct.vec* %c, i64 0, i32 0
1954 %add.ptr = getelementptr inbounds <4 x i32>* %y, i64 -12
1955 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), <4 x i32>* %add.ptr) nounwind
1956 ret void
1957 }
1958
1959 ; test17b: Addr-of a vector nested in a struct
1960 ; ssp attribute
1961 ; Requires no protector.
1962 define void @test17b() nounwind uwtable ssp {
1963 entry:
1964 ; LINUX-I386: test17b:
1965 ; LINUX-I386-NOT: calll __stack_chk_fail
1966 ; LINUX-I386: .cfi_endproc
1967
1968 ; LINUX-X64: test17b:
1969 ; LINUX-X64-NOT: callq __stack_chk_fail
1970 ; LINUX-X64: .cfi_endproc
1971
1972 ; LINUX-KERNEL-X64: test17b:
1973 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1974 ; LINUX-KERNEL-X64: .cfi_endproc
1975
1976 ; DARWIN-X64: test17b:
1977 ; DARWIN-X64-NOT: callq ___stack_chk_fail
1978 ; DARWIN-X64: .cfi_endproc
1979 %c = alloca %struct.vec, align 16
1980 %y = getelementptr inbounds %struct.vec* %c, i64 0, i32 0
1981 %add.ptr = getelementptr inbounds <4 x i32>* %y, i64 -12
1982 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), <4 x i32>* %add.ptr) nounwind
1983 ret void
1984 }
1985
1986 ; test17c: Addr-of a vector nested in a struct
1987 ; sspstrong attribute
1988 ; Requires protector.
1989 define void @test17c() nounwind uwtable sspstrong {
1990 entry:
1991 ; LINUX-I386: test17c:
1992 ; LINUX-I386: mov{{l|q}} %gs:
1993 ; LINUX-I386: calll __stack_chk_fail
1994
1995 ; LINUX-X64: test17c:
1996 ; LINUX-X64: mov{{l|q}} %fs:
1997 ; LINUX-X64: callq __stack_chk_fail
1998
1999 ; LINUX-KERNEL-X64: test17c:
2000 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2001 ; LINUX-KERNEL-X64: callq __stack_chk_fail
2002
2003 ; DARWIN-X64: test17c:
2004 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2005 ; DARWIN-X64: callq ___stack_chk_fail
2006 %c = alloca %struct.vec, align 16
2007 %y = getelementptr inbounds %struct.vec* %c, i64 0, i32 0
2008 %add.ptr = getelementptr inbounds <4 x i32>* %y, i64 -12
2009 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), <4 x i32>* %add.ptr) nounwind
2010 ret void
2011 }
2012
2013 ; test17d: Addr-of a vector nested in a struct
2014 ; sspreq attribute
2015 ; Requires protector.
2016 define void @test17d() nounwind uwtable sspreq {
2017 entry:
2018 ; LINUX-I386: test17d:
2019 ; LINUX-I386: mov{{l|q}} %gs:
2020 ; LINUX-I386: calll __stack_chk_fail
2021
2022 ; LINUX-X64: test17d:
2023 ; LINUX-X64: mov{{l|q}} %fs:
2024 ; LINUX-X64: callq __stack_chk_fail
2025
2026 ; LINUX-KERNEL-X64: test17d:
2027 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2028 ; LINUX-KERNEL-X64: callq __stack_chk_fail
2029
2030 ; DARWIN-X64: test17d:
2031 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2032 ; DARWIN-X64: callq ___stack_chk_fail
2033 %c = alloca %struct.vec, align 16
2034 %y = getelementptr inbounds %struct.vec* %c, i64 0, i32 0
2035 %add.ptr = getelementptr inbounds <4 x i32>* %y, i64 -12
2036 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), <4 x i32>* %add.ptr) nounwind
2037 ret void
2038 }
2039
2040 ; test18a: Addr-of a variable passed into an invoke instruction.
2041 ; no ssp attribute
2042 ; Requires no protector.
2043 define i32 @test18a() uwtable {
2044 entry:
2045 ; LINUX-I386: test18a:
2046 ; LINUX-I386-NOT: calll __stack_chk_fail
2047 ; LINUX-I386: .cfi_endproc
2048
2049 ; LINUX-X64: test18a:
2050 ; LINUX-X64-NOT: callq __stack_chk_fail
2051 ; LINUX-X64: .cfi_endproc
2052
2053 ; LINUX-KERNEL-X64: test18a:
2054 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2055 ; LINUX-KERNEL-X64: .cfi_endproc
2056
2057 ; DARWIN-X64: test18a:
2058 ; DARWIN-X64-NOT: callq ___stack_chk_fail
2059 ; DARWIN-X64: .cfi_endproc
2060 %a = alloca i32, align 4
2061 %exn.slot = alloca i8*
2062 %ehselector.slot = alloca i32
2063 store i32 0, i32* %a, align 4
2064 invoke void @_Z3exceptPi(i32* %a)
2065 to label %invoke.cont unwind label %lpad
2066
2067 invoke.cont:
2068 ret i32 0
2069
2070 lpad:
2071 %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
2072 catch i8* null
2073 ret i32 0
2074 }
2075
2076 ; test18b: Addr-of a variable passed into an invoke instruction.
2077 ; ssp attribute
2078 ; Requires no protector.
2079 define i32 @test18b() uwtable ssp {
2080 entry:
2081 ; LINUX-I386: test18b:
2082 ; LINUX-I386-NOT: calll __stack_chk_fail
2083 ; LINUX-I386: .cfi_endproc
2084
2085 ; LINUX-X64: test18b:
2086 ; LINUX-X64-NOT: callq __stack_chk_fail
2087 ; LINUX-X64: .cfi_endproc
2088
2089 ; LINUX-KERNEL-X64: test18b:
2090 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2091 ; LINUX-KERNEL-X64: .cfi_endproc
2092
2093 ; DARWIN-X64: test18b:
2094 ; DARWIN-X64-NOT: callq ___stack_chk_fail
2095 ; DARWIN-X64: .cfi_endproc
2096 %a = alloca i32, align 4
2097 %exn.slot = alloca i8*
2098 %ehselector.slot = alloca i32
2099 store i32 0, i32* %a, align 4
2100 invoke void @_Z3exceptPi(i32* %a)
2101 to label %invoke.cont unwind label %lpad
2102
2103 invoke.cont:
2104 ret i32 0
2105
2106 lpad:
2107 %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
2108 catch i8* null
2109 ret i32 0
2110 }
2111
2112 ; test18c: Addr-of a variable passed into an invoke instruction.
2113 ; sspstrong attribute
2114 ; Requires protector.
2115 define i32 @test18c() uwtable sspstrong {
2116 entry:
2117 ; LINUX-I386: test18c:
2118 ; LINUX-I386: mov{{l|q}} %gs:
2119 ; LINUX-I386: calll __stack_chk_fail
2120
2121 ; LINUX-X64: test18c:
2122 ; LINUX-X64: mov{{l|q}} %fs:
2123 ; LINUX-X64: callq __stack_chk_fail
2124
2125 ; LINUX-KERNEL-X64: test18c:
2126 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2127 ; LINUX-KERNEL-X64: callq __stack_chk_fail
2128
2129 ; DARWIN-X64: test18c:
2130 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2131 ; DARWIN-X64: callq ___stack_chk_fail
2132 %a = alloca i32, align 4
2133 %exn.slot = alloca i8*
2134 %ehselector.slot = alloca i32
2135 store i32 0, i32* %a, align 4
2136 invoke void @_Z3exceptPi(i32* %a)
2137 to label %invoke.cont unwind label %lpad
2138
2139 invoke.cont:
2140 ret i32 0
2141
2142 lpad:
2143 %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
2144 catch i8* null
2145 ret i32 0
2146 }
2147
2148 ; test18d: Addr-of a variable passed into an invoke instruction.
2149 ; sspreq attribute
2150 ; Requires protector.
2151 define i32 @test18d() uwtable sspreq {
2152 entry:
2153 ; LINUX-I386: test18d:
2154 ; LINUX-I386: mov{{l|q}} %gs:
2155 ; LINUX-I386: calll __stack_chk_fail
2156
2157 ; LINUX-X64: test18d:
2158 ; LINUX-X64: mov{{l|q}} %fs:
2159 ; LINUX-X64: callq __stack_chk_fail
2160
2161 ; LINUX-KERNEL-X64: test18d:
2162 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2163 ; LINUX-KERNEL-X64: callq __stack_chk_fail
2164
2165 ; DARWIN-X64: test18d:
2166 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2167 ; DARWIN-X64: callq ___stack_chk_fail
2168 %a = alloca i32, align 4
2169 %exn.slot = alloca i8*
2170 %ehselector.slot = alloca i32
2171 store i32 0, i32* %a, align 4
2172 invoke void @_Z3exceptPi(i32* %a)
2173 to label %invoke.cont unwind label %lpad
2174
2175 invoke.cont:
2176 ret i32 0
2177
2178 lpad:
2179 %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
2180 catch i8* null
2181 ret i32 0
2182 }
2183
2184 ; test19a: Addr-of a struct element passed into an invoke instruction.
2185 ; (GEP followed by an invoke)
2186 ; no ssp attribute
2187 ; Requires no protector.
2188 define i32 @test19a() uwtable {
2189 entry:
2190 ; LINUX-I386: test19a:
2191 ; LINUX-I386-NOT: calll __stack_chk_fail
2192 ; LINUX-I386: .cfi_endproc
2193
2194 ; LINUX-X64: test19a:
2195 ; LINUX-X64-NOT: callq __stack_chk_fail
2196 ; LINUX-X64: .cfi_endproc
2197
2198 ; LINUX-KERNEL-X64: test19a:
2199 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2200 ; LINUX-KERNEL-X64: .cfi_endproc
2201
2202 ; DARWIN-X64: test19a:
2203 ; DARWIN-X64-NOT: callq ___stack_chk_fail
2204 ; DARWIN-X64: .cfi_endproc
2205 %c = alloca %struct.pair, align 4
2206 %exn.slot = alloca i8*
2207 %ehselector.slot = alloca i32
2208 %a = getelementptr inbounds %struct.pair* %c, i32 0, i32 0
2209 store i32 0, i32* %a, align 4
2210 %a1 = getelementptr inbounds %struct.pair* %c, i32 0, i32 0
2211 invoke void @_Z3exceptPi(i32* %a1)
2212 to label %invoke.cont unwind label %lpad
2213
2214 invoke.cont:
2215 ret i32 0
2216
2217 lpad:
2218 %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
2219 catch i8* null
2220 ret i32 0
2221 }
2222
2223 ; test19b: Addr-of a struct element passed into an invoke instruction.
2224 ; (GEP followed by an invoke)
2225 ; ssp attribute
2226 ; Requires no protector.
2227 define i32 @test19b() uwtable ssp {
2228 entry:
2229 ; LINUX-I386: test19b:
2230 ; LINUX-I386-NOT: calll __stack_chk_fail
2231 ; LINUX-I386: .cfi_endproc
2232
2233 ; LINUX-X64: test19b:
2234 ; LINUX-X64-NOT: callq __stack_chk_fail
2235 ; LINUX-X64: .cfi_endproc
2236
2237 ; LINUX-KERNEL-X64: test19b:
2238 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2239 ; LINUX-KERNEL-X64: .cfi_endproc
2240
2241 ; DARWIN-X64: test19b:
2242 ; DARWIN-X64-NOT: callq ___stack_chk_fail
2243 ; DARWIN-X64: .cfi_endproc
2244 %c = alloca %struct.pair, align 4
2245 %exn.slot = alloca i8*
2246 %ehselector.slot = alloca i32
2247 %a = getelementptr inbounds %struct.pair* %c, i32 0, i32 0
2248 store i32 0, i32* %a, align 4
2249 %a1 = getelementptr inbounds %struct.pair* %c, i32 0, i32 0
2250 invoke void @_Z3exceptPi(i32* %a1)
2251 to label %invoke.cont unwind label %lpad
2252
2253 invoke.cont:
2254 ret i32 0
2255
2256 lpad:
2257 %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
2258 catch i8* null
2259 ret i32 0
2260 }
2261
2262 ; test19c: Addr-of a struct element passed into an invoke instruction.
2263 ; (GEP followed by an invoke)
2264 ; sspstrong attribute
2265 ; Requires protector.
2266 define i32 @test19c() uwtable sspstrong {
2267 entry:
2268 ; LINUX-I386: test19c:
2269 ; LINUX-I386: mov{{l|q}} %gs:
2270 ; LINUX-I386: calll __stack_chk_fail
2271
2272 ; LINUX-X64: test19c:
2273 ; LINUX-X64: mov{{l|q}} %fs:
2274 ; LINUX-X64: callq __stack_chk_fail
2275
2276 ; LINUX-KERNEL-X64: test19c:
2277 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2278 ; LINUX-KERNEL-X64: callq __stack_chk_fail
2279
2280 ; DARWIN-X64: test19c:
2281 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2282 ; DARWIN-X64: callq ___stack_chk_fail
2283 %c = alloca %struct.pair, align 4
2284 %exn.slot = alloca i8*
2285 %ehselector.slot = alloca i32
2286 %a = getelementptr inbounds %struct.pair* %c, i32 0, i32 0
2287 store i32 0, i32* %a, align 4
2288 %a1 = getelementptr inbounds %struct.pair* %c, i32 0, i32 0
2289 invoke void @_Z3exceptPi(i32* %a1)
2290 to label %invoke.cont unwind label %lpad
2291
2292 invoke.cont:
2293 ret i32 0
2294
2295 lpad:
2296 %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
2297 catch i8* null
2298 ret i32 0
2299 }
2300
2301 ; test19d: Addr-of a struct element passed into an invoke instruction.
2302 ; (GEP followed by an invoke)
2303 ; sspreq attribute
2304 ; Requires protector.
2305 define i32 @test19d() uwtable sspreq {
2306 entry:
2307 ; LINUX-I386: test19d:
2308 ; LINUX-I386: mov{{l|q}} %gs:
2309 ; LINUX-I386: calll __stack_chk_fail
2310
2311 ; LINUX-X64: test19d:
2312 ; LINUX-X64: mov{{l|q}} %fs:
2313 ; LINUX-X64: callq __stack_chk_fail
2314
2315 ; LINUX-KERNEL-X64: test19d:
2316 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2317 ; LINUX-KERNEL-X64: callq __stack_chk_fail
2318
2319 ; DARWIN-X64: test19d:
2320 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2321 ; DARWIN-X64: callq ___stack_chk_fail
2322 %c = alloca %struct.pair, align 4
2323 %exn.slot = alloca i8*
2324 %ehselector.slot = alloca i32
2325 %a = getelementptr inbounds %struct.pair* %c, i32 0, i32 0
2326 store i32 0, i32* %a, align 4
2327 %a1 = getelementptr inbounds %struct.pair* %c, i32 0, i32 0
2328 invoke void @_Z3exceptPi(i32* %a1)
2329 to label %invoke.cont unwind label %lpad
2330
2331 invoke.cont:
2332 ret i32 0
2333
2334 lpad:
2335 %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
2336 catch i8* null
2337 ret i32 0
2338 }
2339
2340 ; test20a: Addr-of a pointer
2341 ; no ssp attribute
2342 ; Requires no protector.
2343 define void @test20a() nounwind uwtable {
2344 entry:
2345 ; LINUX-I386: test20a:
2346 ; LINUX-I386-NOT: calll __stack_chk_fail
2347 ; LINUX-I386: .cfi_endproc
2348
2349 ; LINUX-X64: test20a:
2350 ; LINUX-X64-NOT: callq __stack_chk_fail
2351 ; LINUX-X64: .cfi_endproc
2352
2353 ; LINUX-KERNEL-X64: test20a:
2354 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2355 ; LINUX-KERNEL-X64: .cfi_endproc
2356
2357 ; DARWIN-X64: test20a:
2358 ; DARWIN-X64-NOT: callq ___stack_chk_fail
2359 ; DARWIN-X64: .cfi_endproc
2360 %a = alloca i32*, align 8
2361 %b = alloca i32**, align 8
2362 %call = call i32* @getp()
2363 store i32* %call, i32** %a, align 8
2364 store i32** %a, i32*** %b, align 8
2365 %0 = load i32*** %b, align 8
2366 call void @funcall2(i32** %0)
2367 ret void
2368 }
2369
2370 ; test20b: Addr-of a pointer
2371 ; ssp attribute
2372 ; Requires no protector.
2373 define void @test20b() nounwind uwtable ssp {
2374 entry:
2375 ; LINUX-I386: test20b:
2376 ; LINUX-I386-NOT: calll __stack_chk_fail
2377 ; LINUX-I386: .cfi_endproc
2378
2379 ; LINUX-X64: test20b:
2380 ; LINUX-X64-NOT: callq __stack_chk_fail
2381 ; LINUX-X64: .cfi_endproc
2382
2383 ; LINUX-KERNEL-X64: test20b:
2384 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2385 ; LINUX-KERNEL-X64: .cfi_endproc
2386
2387 ; DARWIN-X64: test20b:
2388 ; DARWIN-X64-NOT: callq ___stack_chk_fail
2389 ; DARWIN-X64: .cfi_endproc
2390 %a = alloca i32*, align 8
2391 %b = alloca i32**, align 8
2392 %call = call i32* @getp()
2393 store i32* %call, i32** %a, align 8
2394 store i32** %a, i32*** %b, align 8
2395 %0 = load i32*** %b, align 8
2396 call void @funcall2(i32** %0)
2397 ret void
2398 }
2399
2400 ; test20c: Addr-of a pointer
2401 ; sspstrong attribute
2402 ; Requires protector.
2403 define void @test20c() nounwind uwtable sspstrong {
2404 entry:
2405 ; LINUX-I386: test20c:
2406 ; LINUX-I386: mov{{l|q}} %gs:
2407 ; LINUX-I386: calll __stack_chk_fail
2408
2409 ; LINUX-X64: test20c:
2410 ; LINUX-X64: mov{{l|q}} %fs:
2411 ; LINUX-X64: callq __stack_chk_fail
2412
2413 ; LINUX-KERNEL-X64: test20c:
2414 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2415 ; LINUX-KERNEL-X64: callq __stack_chk_fail
2416
2417 ; DARWIN-X64: test20c:
2418 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2419 ; DARWIN-X64: callq ___stack_chk_fail
2420 %a = alloca i32*, align 8
2421 %b = alloca i32**, align 8
2422 %call = call i32* @getp()
2423 store i32* %call, i32** %a, align 8
2424 store i32** %a, i32*** %b, align 8
2425 %0 = load i32*** %b, align 8
2426 call void @funcall2(i32** %0)
2427 ret void
2428 }
2429
2430 ; test20d: Addr-of a pointer
2431 ; sspreq attribute
2432 ; Requires protector.
2433 define void @test20d() nounwind uwtable sspreq {
2434 entry:
2435 ; LINUX-I386: test20d:
2436 ; LINUX-I386: mov{{l|q}} %gs:
2437 ; LINUX-I386: calll __stack_chk_fail
2438
2439 ; LINUX-X64: test20d:
2440 ; LINUX-X64: mov{{l|q}} %fs:
2441 ; LINUX-X64: callq __stack_chk_fail
2442
2443 ; LINUX-KERNEL-X64: test20d:
2444 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2445 ; LINUX-KERNEL-X64: callq __stack_chk_fail
2446
2447 ; DARWIN-X64: test20d:
2448 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2449 ; DARWIN-X64: callq ___stack_chk_fail
2450 %a = alloca i32*, align 8
2451 %b = alloca i32**, align 8
2452 %call = call i32* @getp()
2453 store i32* %call, i32** %a, align 8
2454 store i32** %a, i32*** %b, align 8
2455 %0 = load i32*** %b, align 8
2456 call void @funcall2(i32** %0)
2457 ret void
2458 }
2459
2460 ; test21a: Addr-of a casted pointer
2461 ; no ssp attribute
2462 ; Requires no protector.
2463 define void @test21a() nounwind uwtable {
2464 entry:
2465 ; LINUX-I386: test21a:
2466 ; LINUX-I386-NOT: calll __stack_chk_fail
2467 ; LINUX-I386: .cfi_endproc
2468
2469 ; LINUX-X64: test21a:
2470 ; LINUX-X64-NOT: callq __stack_chk_fail
2471 ; LINUX-X64: .cfi_endproc
2472
2473 ; LINUX-KERNEL-X64: test21a:
2474 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2475 ; LINUX-KERNEL-X64: .cfi_endproc
2476
2477 ; DARWIN-X64: test21a:
2478 ; DARWIN-X64-NOT: callq ___stack_chk_fail
2479 ; DARWIN-X64: .cfi_endproc
2480 %a = alloca i32*, align 8
2481 %b = alloca float**, align 8
2482 %call = call i32* @getp()
2483 store i32* %call, i32** %a, align 8
2484 %0 = bitcast i32** %a to float**
2485 store float** %0, float*** %b, align 8
2486 %1 = load float*** %b, align 8
2487 call void @funfloat2(float** %1)
2488 ret void
2489 }
2490
2491 ; test21b: Addr-of a casted pointer
2492 ; ssp attribute
2493 ; Requires no protector.
2494 define void @test21b() nounwind uwtable ssp {
2495 entry:
2496 ; LINUX-I386: test21b:
2497 ; LINUX-I386-NOT: calll __stack_chk_fail
2498 ; LINUX-I386: .cfi_endproc
2499
2500 ; LINUX-X64: test21b:
2501 ; LINUX-X64-NOT: callq __stack_chk_fail
2502 ; LINUX-X64: .cfi_endproc
2503
2504 ; LINUX-KERNEL-X64: test21b:
2505 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2506 ; LINUX-KERNEL-X64: .cfi_endproc
2507
2508 ; DARWIN-X64: test21b:
2509 ; DARWIN-X64-NOT: callq ___stack_chk_fail
2510 ; DARWIN-X64: .cfi_endproc
2511 %a = alloca i32*, align 8
2512 %b = alloca float**, align 8
2513 %call = call i32* @getp()
2514 store i32* %call, i32** %a, align 8
2515 %0 = bitcast i32** %a to float**
2516 store float** %0, float*** %b, align 8
2517 %1 = load float*** %b, align 8
2518 call void @funfloat2(float** %1)
2519 ret void
2520 }
2521
2522 ; test21c: Addr-of a casted pointer
2523 ; sspstrong attribute
2524 ; Requires protector.
2525 define void @test21c() nounwind uwtable sspstrong {
2526 entry:
2527 ; LINUX-I386: test21c:
2528 ; LINUX-I386: mov{{l|q}} %gs:
2529 ; LINUX-I386: calll __stack_chk_fail
2530
2531 ; LINUX-X64: test21c:
2532 ; LINUX-X64: mov{{l|q}} %fs:
2533 ; LINUX-X64: callq __stack_chk_fail
2534
2535 ; LINUX-KERNEL-X64: test21c:
2536 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2537 ; LINUX-KERNEL-X64: callq __stack_chk_fail
2538
2539 ; DARWIN-X64: test21c:
2540 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2541 ; DARWIN-X64: callq ___stack_chk_fail
2542 %a = alloca i32*, align 8
2543 %b = alloca float**, align 8
2544 %call = call i32* @getp()
2545 store i32* %call, i32** %a, align 8
2546 %0 = bitcast i32** %a to float**
2547 store float** %0, float*** %b, align 8
2548 %1 = load float*** %b, align 8
2549 call void @funfloat2(float** %1)
2550 ret void
2551 }
2552
2553 ; test21d: Addr-of a casted pointer
2554 ; sspreq attribute
2555 ; Requires protector.
2556 define void @test21d() nounwind uwtable sspreq {
2557 entry:
2558 ; LINUX-I386: test21d:
2559 ; LINUX-I386: mov{{l|q}} %gs:
2560 ; LINUX-I386: calll __stack_chk_fail
2561
2562 ; LINUX-X64: test21d:
2563 ; LINUX-X64: mov{{l|q}} %fs:
2564 ; LINUX-X64: callq __stack_chk_fail
2565
2566 ; LINUX-KERNEL-X64: test21d:
2567 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2568 ; LINUX-KERNEL-X64: callq __stack_chk_fail
2569
2570 ; DARWIN-X64: test21d:
2571 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2572 ; DARWIN-X64: callq ___stack_chk_fail
2573 %a = alloca i32*, align 8
2574 %b = alloca float**, align 8
2575 %call = call i32* @getp()
2576 store i32* %call, i32** %a, align 8
2577 %0 = bitcast i32** %a to float**
2578 store float** %0, float*** %b, align 8
2579 %1 = load float*** %b, align 8
2580 call void @funfloat2(float** %1)
2581 ret void
2582 }
2583
2584 ; test22a: [2 x i8] in a class
2585 ; no ssp attribute
2586 ; Requires no protector.
2587 define signext i8 @test22a() nounwind uwtable {
2588 entry:
2589 ; LINUX-I386: test22a:
2590 ; LINUX-I386-NOT: calll __stack_chk_fail
2591 ; LINUX-I386: .cfi_endproc
2592
2593 ; LINUX-X64: test22a:
2594 ; LINUX-X64-NOT: callq __stack_chk_fail
2595 ; LINUX-X64: .cfi_endproc
2596
2597 ; LINUX-KERNEL-X64: test22a:
2598 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2599 ; LINUX-KERNEL-X64: .cfi_endproc
2600
2601 ; DARWIN-X64: test22a:
2602 ; DARWIN-X64-NOT: callq ___stack_chk_fail
2603 ; DARWIN-X64: .cfi_endproc
2604 %a = alloca %class.A, align 1
2605 %array = getelementptr inbounds %class.A* %a, i32 0, i32 0
2606 %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0
2607 %0 = load i8* %arrayidx, align 1
2608 ret i8 %0
2609 }
2610
2611 ; test22b: [2 x i8] in a class
2612 ; ssp attribute
2613 ; Requires no protector.
2614 define signext i8 @test22b() nounwind uwtable ssp {
2615 entry:
2616 ; LINUX-I386: test22b:
2617 ; LINUX-I386-NOT: calll __stack_chk_fail
2618 ; LINUX-I386: .cfi_endproc
2619
2620 ; LINUX-X64: test22b:
2621 ; LINUX-X64-NOT: callq __stack_chk_fail
2622 ; LINUX-X64: .cfi_endproc
2623
2624 ; LINUX-KERNEL-X64: test22b:
2625 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2626 ; LINUX-KERNEL-X64: .cfi_endproc
2627
2628 ; DARWIN-X64: test22b:
2629 ; DARWIN-X64-NOT: callq ___stack_chk_fail
2630 ; DARWIN-X64: .cfi_endproc
2631 %a = alloca %class.A, align 1
2632 %array = getelementptr inbounds %class.A* %a, i32 0, i32 0
2633 %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0
2634 %0 = load i8* %arrayidx, align 1
2635 ret i8 %0
2636 }
2637
2638 ; test22c: [2 x i8] in a class
2639 ; sspstrong attribute
2640 ; Requires protector.
2641 define signext i8 @test22c() nounwind uwtable sspstrong {
2642 entry:
2643 ; LINUX-I386: test22c:
2644 ; LINUX-I386: mov{{l|q}} %gs:
2645 ; LINUX-I386: calll __stack_chk_fail
2646
2647 ; LINUX-X64: test22c:
2648 ; LINUX-X64: mov{{l|q}} %fs:
2649 ; LINUX-X64: callq __stack_chk_fail
2650
2651 ; LINUX-KERNEL-X64: test22c:
2652 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2653 ; LINUX-KERNEL-X64: callq __stack_chk_fail
2654
2655 ; DARWIN-X64: test22c:
2656 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2657 ; DARWIN-X64: callq ___stack_chk_fail
2658 %a = alloca %class.A, align 1
2659 %array = getelementptr inbounds %class.A* %a, i32 0, i32 0
2660 %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0
2661 %0 = load i8* %arrayidx, align 1
2662 ret i8 %0
2663 }
2664
2665 ; test22d: [2 x i8] in a class
2666 ; sspreq attribute
2667 ; Requires protector.
2668 define signext i8 @test22d() nounwind uwtable sspreq {
2669 entry:
2670 ; LINUX-I386: test22d:
2671 ; LINUX-I386: mov{{l|q}} %gs:
2672 ; LINUX-I386: calll __stack_chk_fail
2673
2674 ; LINUX-X64: test22d:
2675 ; LINUX-X64: mov{{l|q}} %fs:
2676 ; LINUX-X64: callq __stack_chk_fail
2677
2678 ; LINUX-KERNEL-X64: test22d:
2679 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2680 ; LINUX-KERNEL-X64: callq __stack_chk_fail
2681
2682 ; DARWIN-X64: test22d:
2683 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2684 ; DARWIN-X64: callq ___stack_chk_fail
2685 %a = alloca %class.A, align 1
2686 %array = getelementptr inbounds %class.A* %a, i32 0, i32 0
2687 %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0
2688 %0 = load i8* %arrayidx, align 1
2689 ret i8 %0
2690 }
2691
2692 ; test23a: [2 x i8] nested in several layers of structs and unions
2693 ; no ssp attribute
2694 ; Requires no protector.
2695 define signext i8 @test23a() nounwind uwtable {
2696 entry:
2697 ; LINUX-I386: test23a:
2698 ; LINUX-I386-NOT: calll __stack_chk_fail
2699 ; LINUX-I386: .cfi_endproc
2700
2701 ; LINUX-X64: test23a:
2702 ; LINUX-X64-NOT: callq __stack_chk_fail
2703 ; LINUX-X64: .cfi_endproc
2704
2705 ; LINUX-KERNEL-X64: test23a:
2706 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2707 ; LINUX-KERNEL-X64: .cfi_endproc
2708
2709 ; DARWIN-X64: test23a:
2710 ; DARWIN-X64-NOT: callq ___stack_chk_fail
2711 ; DARWIN-X64: .cfi_endproc
2712 %x = alloca %struct.deep, align 1
2713 %b = getelementptr inbounds %struct.deep* %x, i32 0, i32 0
2714 %c = bitcast %union.anon* %b to %struct.anon*
2715 %d = getelementptr inbounds %struct.anon* %c, i32 0, i32 0
2716 %e = getelementptr inbounds %struct.anon.0* %d, i32 0, i32 0
2717 %array = bitcast %union.anon.1* %e to [2 x i8]*
2718 %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0
2719 %0 = load i8* %arrayidx, align 1
2720 ret i8 %0
2721 }
2722
2723 ; test23b: [2 x i8] nested in several layers of structs and unions
2724 ; ssp attribute
2725 ; Requires no protector.
2726 define signext i8 @test23b() nounwind uwtable ssp {
2727 entry:
2728 ; LINUX-I386: test23b:
2729 ; LINUX-I386-NOT: calll __stack_chk_fail
2730 ; LINUX-I386: .cfi_endproc
2731
2732 ; LINUX-X64: test23b:
2733 ; LINUX-X64-NOT: callq __stack_chk_fail
2734 ; LINUX-X64: .cfi_endproc
2735
2736 ; LINUX-KERNEL-X64: test23b:
2737 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2738 ; LINUX-KERNEL-X64: .cfi_endproc
2739
2740 ; DARWIN-X64: test23b:
2741 ; DARWIN-X64-NOT: callq ___stack_chk_fail
2742 ; DARWIN-X64: .cfi_endproc
2743 %x = alloca %struct.deep, align 1
2744 %b = getelementptr inbounds %struct.deep* %x, i32 0, i32 0
2745 %c = bitcast %union.anon* %b to %struct.anon*
2746 %d = getelementptr inbounds %struct.anon* %c, i32 0, i32 0
2747 %e = getelementptr inbounds %struct.anon.0* %d, i32 0, i32 0
2748 %array = bitcast %union.anon.1* %e to [2 x i8]*
2749 %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0
2750 %0 = load i8* %arrayidx, align 1
2751 ret i8 %0
2752 }
2753
2754 ; test23c: [2 x i8] nested in several layers of structs and unions
2755 ; sspstrong attribute
2756 ; Requires protector.
2757 define signext i8 @test23c() nounwind uwtable sspstrong {
2758 entry:
2759 ; LINUX-I386: test23c:
2760 ; LINUX-I386: mov{{l|q}} %gs:
2761 ; LINUX-I386: calll __stack_chk_fail
2762
2763 ; LINUX-X64: test23c:
2764 ; LINUX-X64: mov{{l|q}} %fs:
2765 ; LINUX-X64: callq __stack_chk_fail
2766
2767 ; LINUX-KERNEL-X64: test23c:
2768 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2769 ; LINUX-KERNEL-X64: callq __stack_chk_fail
2770
2771 ; DARWIN-X64: test23c:
2772 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2773 ; DARWIN-X64: callq ___stack_chk_fail
2774 %x = alloca %struct.deep, align 1
2775 %b = getelementptr inbounds %struct.deep* %x, i32 0, i32 0
2776 %c = bitcast %union.anon* %b to %struct.anon*
2777 %d = getelementptr inbounds %struct.anon* %c, i32 0, i32 0
2778 %e = getelementptr inbounds %struct.anon.0* %d, i32 0, i32 0
2779 %array = bitcast %union.anon.1* %e to [2 x i8]*
2780 %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0
2781 %0 = load i8* %arrayidx, align 1
2782 ret i8 %0
2783 }
2784
2785 ; test23d: [2 x i8] nested in several layers of structs and unions
2786 ; sspreq attribute
2787 ; Requires protector.
2788 define signext i8 @test23d() nounwind uwtable sspreq {
2789 entry:
2790 ; LINUX-I386: test23d:
2791 ; LINUX-I386: mov{{l|q}} %gs:
2792 ; LINUX-I386: calll __stack_chk_fail
2793
2794 ; LINUX-X64: test23d:
2795 ; LINUX-X64: mov{{l|q}} %fs:
2796 ; LINUX-X64: callq __stack_chk_fail
2797
2798 ; LINUX-KERNEL-X64: test23d:
2799 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2800 ; LINUX-KERNEL-X64: callq __stack_chk_fail
2801
2802 ; DARWIN-X64: test23d:
2803 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2804 ; DARWIN-X64: callq ___stack_chk_fail
2805 %x = alloca %struct.deep, align 1
2806 %b = getelementptr inbounds %struct.deep* %x, i32 0, i32 0
2807 %c = bitcast %union.anon* %b to %struct.anon*
2808 %d = getelementptr inbounds %struct.anon* %c, i32 0, i32 0
2809 %e = getelementptr inbounds %struct.anon.0* %d, i32 0, i32 0
2810 %array = bitcast %union.anon.1* %e to [2 x i8]*
2811 %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0
2812 %0 = load i8* %arrayidx, align 1
2813 ret i8 %0
2814 }
2815
2816 ; test24a: Variable sized alloca
2817 ; no ssp attribute
2818 ; Requires no protector.
2819 define void @test24a(i32 %n) nounwind uwtable {
2820 entry:
2821 ; LINUX-I386: test24a:
2822 ; LINUX-I386-NOT: calll __stack_chk_fail
2823 ; LINUX-I386: .cfi_endproc
2824
2825 ; LINUX-X64: test24a:
2826 ; LINUX-X64-NOT: callq __stack_chk_fail
2827 ; LINUX-X64: .cfi_endproc
2828
2829 ; LINUX-KERNEL-X64: test24a:
2830 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2831 ; LINUX-KERNEL-X64: .cfi_endproc
2832
2833 ; DARWIN-X64: test24a:
2834 ; DARWIN-X64-NOT: callq ___stack_chk_fail
2835 ; DARWIN-X64: .cfi_endproc
2836 %n.addr = alloca i32, align 4
2837 %a = alloca i32*, align 8
2838 store i32 %n, i32* %n.addr, align 4
2839 %0 = load i32* %n.addr, align 4
2840 %conv = sext i32 %0 to i64
2841 %1 = alloca i8, i64 %conv
2842 %2 = bitcast i8* %1 to i32*
2843 store i32* %2, i32** %a, align 8
2844 ret void
2845 }
2846
2847 ; test24b: Variable sized alloca
2848 ; ssp attribute
2849 ; Requires protector.
2850 define void @test24b(i32 %n) nounwind uwtable ssp {
2851 entry:
2852 ; LINUX-I386: test24b:
2853 ; LINUX-I386: mov{{l|q}} %gs:
2854 ; LINUX-I386: calll __stack_chk_fail
2855
2856 ; LINUX-X64: test24b:
2857 ; LINUX-X64: mov{{l|q}} %fs:
2858 ; LINUX-X64: callq __stack_chk_fail
2859
2860 ; LINUX-KERNEL-X64: test24b:
2861 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2862 ; LINUX-KERNEL-X64: callq __stack_chk_fail
2863
2864 ; DARWIN-X64: test24b:
2865 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2866 ; DARWIN-X64: callq ___stack_chk_fail
2867 %n.addr = alloca i32, align 4
2868 %a = alloca i32*, align 8
2869 store i32 %n, i32* %n.addr, align 4
2870 %0 = load i32* %n.addr, align 4
2871 %conv = sext i32 %0 to i64
2872 %1 = alloca i8, i64 %conv
2873 %2 = bitcast i8* %1 to i32*
2874 store i32* %2, i32** %a, align 8
2875 ret void
2876 }
2877
2878 ; test24c: Variable sized alloca
2879 ; sspstrong attribute
2880 ; Requires protector.
2881 define void @test24c(i32 %n) nounwind uwtable sspstrong {
2882 entry:
2883 ; LINUX-I386: test24c:
2884 ; LINUX-I386: mov{{l|q}} %gs:
2885 ; LINUX-I386: calll __stack_chk_fail
2886
2887 ; LINUX-X64: test24c:
2888 ; LINUX-X64: mov{{l|q}} %fs:
2889 ; LINUX-X64: callq __stack_chk_fail
2890
2891 ; LINUX-KERNEL-X64: test24c:
2892 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2893 ; LINUX-KERNEL-X64: callq __stack_chk_fail
2894
2895 ; DARWIN-X64: test24c:
2896 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2897 ; DARWIN-X64: callq ___stack_chk_fail
2898 %n.addr = alloca i32, align 4
2899 %a = alloca i32*, align 8
2900 store i32 %n, i32* %n.addr, align 4
2901 %0 = load i32* %n.addr, align 4
2902 %conv = sext i32 %0 to i64
2903 %1 = alloca i8, i64 %conv
2904 %2 = bitcast i8* %1 to i32*
2905 store i32* %2, i32** %a, align 8
2906 ret void
2907 }
2908
2909 ; test24d: Variable sized alloca
2910 ; sspreq attribute
2911 ; Requires protector.
2912 define void @test24d(i32 %n) nounwind uwtable sspreq {
2913 entry:
2914 ; LINUX-I386: test24d:
2915 ; LINUX-I386: mov{{l|q}} %gs:
2916 ; LINUX-I386: calll __stack_chk_fail
2917
2918 ; LINUX-X64: test24d:
2919 ; LINUX-X64: mov{{l|q}} %fs:
2920 ; LINUX-X64: callq __stack_chk_fail
2921
2922 ; LINUX-KERNEL-X64: test24d:
2923 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2924 ; LINUX-KERNEL-X64: callq __stack_chk_fail
2925
2926 ; DARWIN-X64: test24d:
2927 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2928 ; DARWIN-X64: callq ___stack_chk_fail
2929 %n.addr = alloca i32, align 4
2930 %a = alloca i32*, align 8
2931 store i32 %n, i32* %n.addr, align 4
2932 %0 = load i32* %n.addr, align 4
2933 %conv = sext i32 %0 to i64
2934 %1 = alloca i8, i64 %conv
2935 %2 = bitcast i8* %1 to i32*
2936 store i32* %2, i32** %a, align 8
2937 ret void
2938 }
2939
2940 ; test25a: array of [4 x i32]
2941 ; no ssp attribute
2942 ; Requires no protector.
2943 define i32 @test25a() nounwind uwtable {
2944 entry:
2945 ; LINUX-I386: test25a:
2946 ; LINUX-I386-NOT: calll __stack_chk_fail
2947 ; LINUX-I386: .cfi_endproc
2948
2949 ; LINUX-X64: test25a:
2950 ; LINUX-X64-NOT: callq __stack_chk_fail
2951 ; LINUX-X64: .cfi_endproc
2952
2953 ; LINUX-KERNEL-X64: test25a:
2954 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2955 ; LINUX-KERNEL-X64: .cfi_endproc
2956
2957 ; DARWIN-X64: test25a:
2958 ; DARWIN-X64-NOT: callq ___stack_chk_fail
2959 ; DARWIN-X64: .cfi_endproc
2960 %a = alloca [4 x i32], align 16
2961 %arrayidx = getelementptr inbounds [4 x i32]* %a, i32 0, i64 0
2962 %0 = load i32* %arrayidx, align 4
2963 ret i32 %0
2964 }
2965
2966 ; test25b: array of [4 x i32]
2967 ; ssp attribute
2968 ; Requires no protector, except for Darwin which _does_ require a protector.
2969 define i32 @test25b() nounwind uwtable ssp {
2970 entry:
2971 ; LINUX-I386: test25b:
2972 ; LINUX-I386-NOT: calll __stack_chk_fail
2973 ; LINUX-I386: .cfi_endproc
2974
2975 ; LINUX-X64: test25b:
2976 ; LINUX-X64-NOT: callq __stack_chk_fail
2977 ; LINUX-X64: .cfi_endproc
2978
2979 ; LINUX-KERNEL-X64: test25b:
2980 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2981 ; LINUX-KERNEL-X64: .cfi_endproc
2982
2983 ; DARWIN-X64: test25b:
2984 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2985 ; DARWIN-X64: callq ___stack_chk_fail
2986 %a = alloca [4 x i32], align 16
2987 %arrayidx = getelementptr inbounds [4 x i32]* %a, i32 0, i64 0
2988 %0 = load i32* %arrayidx, align 4
2989 ret i32 %0
2990 }
2991
2992 ; test25c: array of [4 x i32]
2993 ; sspstrong attribute
2994 ; Requires protector.
2995 define i32 @test25c() nounwind uwtable sspstrong {
2996 entry:
2997 ; LINUX-I386: test25c:
2998 ; LINUX-I386: mov{{l|q}} %gs:
2999 ; LINUX-I386: calll __stack_chk_fail
3000
3001 ; LINUX-X64: test25c:
3002 ; LINUX-X64: mov{{l|q}} %fs:
3003 ; LINUX-X64: callq __stack_chk_fail
3004
3005 ; LINUX-KERNEL-X64: test25c:
3006 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
3007 ; LINUX-KERNEL-X64: callq __stack_chk_fail
3008
3009 ; DARWIN-X64: test25c:
3010 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3011 ; DARWIN-X64: callq ___stack_chk_fail
3012 %a = alloca [4 x i32], align 16
3013 %arrayidx = getelementptr inbounds [4 x i32]* %a, i32 0, i64 0
3014 %0 = load i32* %arrayidx, align 4
3015 ret i32 %0
3016 }
3017
3018 ; test25d: array of [4 x i32]
3019 ; sspreq attribute
3020 ; Requires protector.
3021 define i32 @test25d() nounwind uwtable sspreq {
3022 entry:
3023 ; LINUX-I386: test25d:
3024 ; LINUX-I386: mov{{l|q}} %gs:
3025 ; LINUX-I386: calll __stack_chk_fail
3026
3027 ; LINUX-X64: test25d:
3028 ; LINUX-X64: mov{{l|q}} %fs:
3029 ; LINUX-X64: callq __stack_chk_fail
3030
3031 ; LINUX-KERNEL-X64: test25d:
3032 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
3033 ; LINUX-KERNEL-X64: callq __stack_chk_fail
3034
3035 ; DARWIN-X64: test25d:
3036 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3037 ; DARWIN-X64: callq ___stack_chk_fail
3038 %a = alloca [4 x i32], align 16
3039 %arrayidx = getelementptr inbounds [4 x i32]* %a, i32 0, i64 0
3040 %0 = load i32* %arrayidx, align 4
3041 ret i32 %0
3042 }
3043
3044 ; test26: Nested structure, no arrays, no address-of expressions.
3045 ; Verify that the resulting gep-of-gep does not incorrectly trigger
3046 ; a stack protector.
3047 ; ssptrong attribute
3048 ; Requires no protector.
3049 define void @test26() nounwind uwtable sspstrong {
3050 entry:
3051 ; LINUX-I386: test26:
3052 ; LINUX-I386-NOT: calll __stack_chk_fail
3053 ; LINUX-I386: .cfi_endproc
3054
3055 ; LINUX-X64: test26:
3056 ; LINUX-X64-NOT: callq __stack_chk_fail
3057 ; LINUX-X64: .cfi_endproc
3058
3059 ; LINUX-KERNEL-X64: test26:
3060 ; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
3061 ; LINUX-KERNEL-X64: .cfi_endproc
3062
3063 ; DARWIN-X64: test26:
3064 ; DARWIN-X64-NOT: callq ___stack_chk_fail
3065 ; DARWIN-X64: .cfi_endproc
3066 %c = alloca %struct.nest, align 4
3067 %b = getelementptr inbounds %struct.nest* %c, i32 0, i32 1
3068 %_a = getelementptr inbounds %struct.pair* %b, i32 0, i32 0
3069 %0 = load i32* %_a, align 4
3070 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32 %0)
3071 ret void
3072 }
3073
3074 ; test27: Address-of a structure taken in a function with a loop where
3075 ; the alloca is an incoming value to a PHI node and a use of that PHI
3076 ; node is also an incoming value.
3077 ; Verify that the address-of analysis does not get stuck in infinite
3078 ; recursion when chasing the alloca through the PHI nodes.
3079 ; Requires protector.
3080 define i32 @test27(i32 %arg) nounwind uwtable sspstrong {
3081 bb:
3082 ; LINUX-I386: test27:
3083 ; LINUX-I386: mov{{l|q}} %gs:
3084 ; LINUX-I386: calll __stack_chk_fail
3085
3086 ; LINUX-X64: test27:
3087 ; LINUX-X64: mov{{l|q}} %fs:
3088 ; LINUX-X64: callq __stack_chk_fail
3089
3090 ; LINUX-KERNEL-X64: test27:
3091 ; LINUX-KERNEL-X64: mov{{l|q}} %gs:
3092 ; LINUX-KERNEL-X64: callq __stack_chk_fail
3093
3094 ; DARWIN-X64: test27:
3095 ; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3096 ; DARWIN-X64: callq ___stack_chk_fail
3097 %tmp = alloca %struct.small*, align 8
3098 %tmp1 = call i32 (...)* @dummy(%struct.small** %tmp) nounwind
3099 %tmp2 = load %struct.small** %tmp, align 8
3100 %tmp3 = ptrtoint %struct.small* %tmp2 to i64
3101 %tmp4 = trunc i64 %tmp3 to i32
3102 %tmp5 = icmp sgt i32 %tmp4, 0
3103 br i1 %tmp5, label %bb6, label %bb21
3104
3105 bb6: ; preds = %bb17, %bb
3106 %tmp7 = phi %struct.small* [ %tmp19, %bb17 ], [ %tmp2, %bb ]
3107 %tmp8 = phi i64 [ %tmp20, %bb17 ], [ 1, %bb ]
3108 %tmp9 = phi i32 [ %tmp14, %bb17 ], [ %tmp1, %bb ]
3109 %tmp10 = getelementptr inbounds %struct.small* %tmp7, i64 0, i32 0
3110 %tmp11 = load i8* %tmp10, align 1
3111 %tmp12 = icmp eq i8 %tmp11, 1
3112 %tmp13 = add nsw i32 %tmp9, 8
3113 %tmp14 = select i1 %tmp12, i32 %tmp13, i32 %tmp9
3114 %tmp15 = trunc i64 %tmp8 to i32
3115 %tmp16 = icmp eq i32 %tmp15, %tmp4
3116 br i1 %tmp16, label %bb21, label %bb17
3117
3118 bb17: ; preds = %bb6
3119 %tmp18 = getelementptr inbounds %struct.small** %tmp, i64 %tmp8
3120 %tmp19 = load %struct.small** %tmp18, align 8
3121 %tmp20 = add i64 %tmp8, 1
3122 br label %bb6
3123
3124 bb21: ; preds = %bb6, %bb
3125 %tmp22 = phi i32 [ %tmp1, %bb ], [ %tmp14, %bb6 ]
3126 %tmp23 = call i32 (...)* @dummy(i32 %tmp22) nounwind
3127 ret i32 undef
3128 }
3129
3130 declare double @testi_aux()
6333131 declare i8* @strcpy(i8*, i8*)
6343132 declare i32 @printf(i8*, ...)
3133 declare void @funcall(i32*)
3134 declare void @funcall2(i32**)
3135 declare void @funfloat(float*)
3136 declare void @funfloat2(float**)
3137 declare void @_Z3exceptPi(i32*)
3138 declare i32 @__gxx_personality_v0(...)
3139 declare i32* @getp()
3140 declare i32 @dummy(...)