llvm.org GIT mirror llvm / ba7e756
Start inferring side effect information more aggressively, and fix many bugs in the x86 backend where instructions were not marked maystore/mayload, and perf issues where instructions were not marked neverHasSideEffects. It would be really nice if we could write patterns for copy instructions. I have audited all the x86 instructions down to MOVDQAmr. The flags on others and on other targets are probably not right in all cases, but no clients currently use this info that are enabled by default. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45829 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 11 years ago
10 changed file(s) with 198 addition(s) and 108 deletion(s). Raw diff Collapse all Expand all
203203 bit hasCtrlDep = 0; // Does this instruction r/w ctrl-flow chains?
204204 bit isNotDuplicable = 0; // Is it unsafe to duplicate this instruction?
205205
206 // Side effect flags - If neither of these flags is set, then the instruction
207 // *always* has side effects. When set, the flags have these meanings:
208 //
209 // neverHasSideEffects - The instruction has no side effects that are not
210 // captured by any operands of the instruction or other flags, and when
211 // *all* instances of the instruction of that opcode have no side effects.
206 // Side effect flags - When set, the flags have these meanings:
207 //
208 // hasSideEffects - The instruction has side effects that are not
209 // captured by any operands of the instruction or other flags.
212210 // mayHaveSideEffects - Some instances of the instruction can have side
213211 // effects. The virtual method "isReallySideEffectFree" is called to
214212 // determine this. Load instructions are an example of where this is
215213 // useful. In general, loads always have side effects. However, loads from
216214 // constant pools don't. Individual back ends make this determination.
215 // neverHasSideEffects - Set on an instruction with no pattern if it has no
216 // side effects.
217 bit hasSideEffects = 0;
218 bit mayHaveSideEffects = 0;
217219 bit neverHasSideEffects = 0;
218 bit mayHaveSideEffects = 0;
219220
220221 InstrItinClass Itinerary = NoItinerary;// Execution steps used for scheduling.
221222
342343 let InOperandList = (ops variable_ops);
343344 let AsmString = "";
344345 let Namespace = "TargetInstrInfo";
346 let neverHasSideEffects = 1;
345347 }
346348 def INSERT_SUBREG : Instruction {
347349 let OutOperandList = (ops variable_ops);
348350 let InOperandList = (ops variable_ops);
349351 let AsmString = "";
350352 let Namespace = "TargetInstrInfo";
353 let neverHasSideEffects = 1;
351354 }
352355
353356 //===----------------------------------------------------------------------===//
130130 //===----------------------------------------------------------------------===//
131131 // Miscellaneous Instructions...
132132 //
133 let Defs = [RBP,RSP], Uses = [RBP,RSP] in
133 let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, neverHasSideEffects = 1 in
134134 def LEAVE64 : I<0xC9, RawFrm,
135135 (outs), (ins), "leave", []>;
136 let Defs = [RSP], Uses = [RSP] in {
136 let Defs = [RSP], Uses = [RSP], neverHasSideEffects=1 in {
137 let mayLoad = 1 in
137138 def POP64r : I<0x58, AddRegFrm,
138139 (outs GR64:$reg), (ins), "pop{q}\t$reg", []>;
140 let mayStore = 1 in
139141 def PUSH64r : I<0x50, AddRegFrm,
140142 (outs), (ins GR64:$reg), "push{q}\t$reg", []>;
141143 }
142144
143 let Defs = [RSP, EFLAGS], Uses = [RSP] in
145 let Defs = [RSP, EFLAGS], Uses = [RSP], mayLoad = 1 in
144146 def POPFQ : I<0x9D, RawFrm, (outs), (ins), "popf", []>, REX_W;
145 let Defs = [RSP], Uses = [RSP, EFLAGS] in
147 let Defs = [RSP], Uses = [RSP, EFLAGS], mayStore = 1 in
146148 def PUSHFQ : I<0x9C, RawFrm, (outs), (ins), "pushf", []>;
147149
148150 def LEA64_32r : I<0x8D, MRMSrcMem,
159161 "bswap{q}\t$dst",
160162 [(set GR64:$dst, (bswap GR64:$src))]>, TB;
161163 // Exchange
164 let neverHasSideEffects = 1 in {
162165 def XCHG64rr : RI<0x87, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
163166 "xchg{q}\t{$src2|$src1}, {$src1|$src2}", []>;
167 let mayLoad = 1, mayStore = 1 in {
164168 def XCHG64mr : RI<0x87, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
165169 "xchg{q}\t{$src2|$src1}, {$src1|$src2}", []>;
166170 def XCHG64rm : RI<0x87, MRMSrcMem, (outs), (ins GR64:$src1, i64mem:$src2),
167171 "xchg{q}\t{$src2|$src1}, {$src1|$src2}", []>;
172 }
173 }
168174
169175 // Bit scan instructions.
170176 let Defs = [EFLAGS] in {
197203 // Move Instructions...
198204 //
199205
206 let neverHasSideEffects = 1 in
200207 def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
201208 "mov{q}\t{$src, $dst|$dst, $src}", []>;
202209
255262 "movz{wq|x}\t{$src, $dst|$dst, $src}",
256263 [(set GR64:$dst, (zextloadi64i16 addr:$src))]>, TB;
257264
258 let Defs = [RAX], Uses = [EAX] in
259 def CDQE : RI<0x98, RawFrm, (outs), (ins),
260 "{cltq|cdqe}", []>; // RAX = signext(EAX)
261
262 let Defs = [RAX,RDX], Uses = [RAX] in
263 def CQO : RI<0x99, RawFrm, (outs), (ins),
264 "{cqto|cqo}", []>; // RDX:RAX = signext(RAX)
265 let neverHasSideEffects = 1 in {
266 let Defs = [RAX], Uses = [EAX] in
267 def CDQE : RI<0x98, RawFrm, (outs), (ins),
268 "{cltq|cdqe}", []>; // RAX = signext(EAX)
269
270 let Defs = [RAX,RDX], Uses = [RAX] in
271 def CQO : RI<0x99, RawFrm, (outs), (ins),
272 "{cqto|cqo}", []>; // RDX:RAX = signext(RAX)
273 }
265274
266275 //===----------------------------------------------------------------------===//
267276 // Arithmetic Instructions...
386395 } // Defs = [EFLAGS]
387396
388397 // Unsigned multiplication
389 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in {
398 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX], neverHasSideEffects = 1 in {
390399 def MUL64r : RI<0xF7, MRM4r, (outs), (ins GR64:$src),
391400 "mul{q}\t$src", []>; // RAX,RDX = RAX*GR64
401 let mayLoad = 1 in
392402 def MUL64m : RI<0xF7, MRM4m, (outs), (ins i64mem:$src),
393403 "mul{q}\t$src", []>; // RAX,RDX = RAX*[mem64]
394404
395405 // Signed multiplication
396406 def IMUL64r : RI<0xF7, MRM5r, (outs), (ins GR64:$src),
397407 "imul{q}\t$src", []>; // RAX,RDX = RAX*GR64
408 let mayLoad = 1 in
398409 def IMUL64m : RI<0xF7, MRM5m, (outs), (ins i64mem:$src),
399410 "imul{q}\t$src", []>; // RAX,RDX = RAX*[mem64]
400411 }
431442 } // Defs = [EFLAGS]
432443
433444 // Unsigned division / remainder
445 let neverHasSideEffects = 1 in {
434446 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in {
435447 def DIV64r : RI<0xF7, MRM6r, (outs), (ins GR64:$src), // RDX:RAX/r64 = RAX,RDX
436448 "div{q}\t$src", []>;
437 def DIV64m : RI<0xF7, MRM6m, (outs), (ins i64mem:$src), // RDX:RAX/[mem64] = RAX,RDX
438 "div{q}\t$src", []>;
439
440449 // Signed division / remainder
441450 def IDIV64r: RI<0xF7, MRM7r, (outs), (ins GR64:$src), // RDX:RAX/r64 = RAX,RDX
442451 "idiv{q}\t$src", []>;
452 let mayLoad = 1 in {
453 def DIV64m : RI<0xF7, MRM6m, (outs), (ins i64mem:$src), // RDX:RAX/[mem64] = RAX,RDX
454 "div{q}\t$src", []>;
443455 def IDIV64m: RI<0xF7, MRM7m, (outs), (ins i64mem:$src), // RDX:RAX/[mem64] = RAX,RDX
444456 "idiv{q}\t$src", []>;
457 }
458 }
445459 }
446460
447461 // Unary instructions
10341048 def CVTSI2SS64rm: RSSI<0x2A, MRMSrcMem, (outs FR32:$dst), (ins i64mem:$src),
10351049 "cvtsi2ss{q}\t{$src, $dst|$dst, $src}",
10361050 [(set FR32:$dst, (sint_to_fp (loadi64 addr:$src)))]>;
1037 let isTwoAddress = 1 in {
1051 let isTwoAddress = 1, neverHasSideEffects = 1 in {
10381052 def Int_CVTSI2SS64rr: RSSI<0x2A, MRMSrcReg,
10391053 (outs VR128:$dst), (ins VR128:$src1, GR64:$src2),
10401054 "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}",
10411055 []>; // TODO: add intrinsic
1056 let mayLoad = 1 in
10421057 def Int_CVTSI2SS64rm: RSSI<0x2A, MRMSrcMem,
10431058 (outs VR128:$dst), (ins VR128:$src1, i64mem:$src2),
10441059 "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}",
3131 def SDTX86CwdStore : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
3232
3333 def X86fpget : SDNode<"X86ISD::FP_GET_RESULT", SDTX86FpGet,
34 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
34 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
3535 def X86fpset : SDNode<"X86ISD::FP_SET_RESULT", SDTX86FpSet,
36 [SDNPHasChain, SDNPOutFlag]>;
37 def X86fld : SDNode<"X86ISD::FLD", SDTX86Fld,
38 [SDNPHasChain, SDNPMayLoad]>;
39 def X86fst : SDNode<"X86ISD::FST", SDTX86Fst,
40 [SDNPHasChain, SDNPInFlag, SDNPMayStore]>;
41 def X86fild : SDNode<"X86ISD::FILD", SDTX86Fild,
42 [SDNPHasChain, SDNPMayLoad]>;
43 def X86fildflag : SDNode<"X86ISD::FILD_FLAG",SDTX86Fild,
44 [SDNPHasChain, SDNPOutFlag, SDNPMayLoad]>;
36 [SDNPHasChain, SDNPOutFlag]>;
37 def X86fld : SDNode<"X86ISD::FLD", SDTX86Fld,
38 [SDNPHasChain, SDNPMayLoad]>;
39 def X86fst : SDNode<"X86ISD::FST", SDTX86Fst,
40 [SDNPHasChain, SDNPInFlag, SDNPMayStore]>;
41 def X86fild : SDNode<"X86ISD::FILD", SDTX86Fild,
42 [SDNPHasChain, SDNPMayLoad]>;
43 def X86fildflag : SDNode<"X86ISD::FILD_FLAG", SDTX86Fild,
44 [SDNPHasChain, SDNPOutFlag, SDNPMayLoad]>;
4545 def X86fp_to_i16mem : SDNode<"X86ISD::FP_TO_INT16_IN_MEM", SDTX86FpToIMem,
46 [SDNPHasChain]>;
46 [SDNPHasChain, SDNPMayStore]>;
4747 def X86fp_to_i32mem : SDNode<"X86ISD::FP_TO_INT32_IN_MEM", SDTX86FpToIMem,
48 [SDNPHasChain]>;
48 [SDNPHasChain, SDNPMayStore]>;
4949 def X86fp_to_i64mem : SDNode<"X86ISD::FP_TO_INT64_IN_MEM", SDTX86FpToIMem,
50 [SDNPHasChain]>;
50 [SDNPHasChain, SDNPMayStore]>;
5151 def X86fp_cwd_get16 : SDNode<"X86ISD::FNSTCW16m", SDTX86CwdStore,
52 [SDNPHasChain]>;
52 [SDNPHasChain, SDNPMayStore, SDNPSideEffect]>;
5353
5454 //===----------------------------------------------------------------------===//
5555 // FPStack pattern fragments
207207 [(set RFP80:$dst,
208208 (OpNode RFP80:$src1, (f80 (extloadf64 addr:$src2))))]>;
209209 def _F32m : FPI<0xD8, fp, (outs), (ins f32mem:$src),
210 !strconcat("f", !strconcat(asmstring, "{s}\t$src"))>;
210 !strconcat("f", !strconcat(asmstring, "{s}\t$src"))> { let mayLoad = 1; }
211211 def _F64m : FPI<0xDC, fp, (outs), (ins f64mem:$src),
212 !strconcat("f", !strconcat(asmstring, "{l}\t$src"))>;
212 !strconcat("f", !strconcat(asmstring, "{l}\t$src"))> { let mayLoad = 1; }
213213 // ST(0) = ST(0) + [memint]
214214 def _FpI16m32 : FpIf32<(outs RFP32:$dst), (ins RFP32:$src1, i16mem:$src2), OneArgFPRW,
215215 [(set RFP32:$dst, (OpNode RFP32:$src1,
230230 [(set RFP80:$dst, (OpNode RFP80:$src1,
231231 (X86fild addr:$src2, i32)))]>;
232232 def _FI16m : FPI<0xDE, fp, (outs), (ins i16mem:$src),
233 !strconcat("fi", !strconcat(asmstring, "{s}\t$src"))>;
233 !strconcat("fi", !strconcat(asmstring, "{s}\t$src"))> { let mayLoad = 1; }
234234 def _FI32m : FPI<0xDA, fp, (outs), (ins i32mem:$src),
235 !strconcat("fi", !strconcat(asmstring, "{l}\t$src"))>;
235 !strconcat("fi", !strconcat(asmstring, "{l}\t$src"))> { let mayLoad = 1; }
236236 }
237237
238238 defm ADD : FPBinary_rr;
391391 [(truncstoref64 RFP80:$src, addr:$op)]>;
392392 // FST does not support 80-bit memory target; FSTP must be used.
393393
394 let mayStore = 1 in {
394395 def ST_FpP32m : FpIf32<(outs), (ins f32mem:$op, RFP32:$src), OneArgFP, []>;
395396 def ST_FpP64m32 : FpIf64<(outs), (ins f32mem:$op, RFP64:$src), OneArgFP, []>;
396397 def ST_FpP64m : FpIf64<(outs), (ins f64mem:$op, RFP64:$src), OneArgFP, []>;
397398 def ST_FpP80m32 : FpI_<(outs), (ins f32mem:$op, RFP80:$src), OneArgFP, []>;
398399 def ST_FpP80m64 : FpI_<(outs), (ins f64mem:$op, RFP80:$src), OneArgFP, []>;
400 }
399401 def ST_FpP80m : FpI_<(outs), (ins f80mem:$op, RFP80:$src), OneArgFP,
400402 [(store RFP80:$src, addr:$op)]>;
403 let mayStore = 1 in {
401404 def IST_Fp16m32 : FpIf32<(outs), (ins i16mem:$op, RFP32:$src), OneArgFP, []>;
402405 def IST_Fp32m32 : FpIf32<(outs), (ins i32mem:$op, RFP32:$src), OneArgFP, []>;
403406 def IST_Fp64m32 : FpIf32<(outs), (ins i64mem:$op, RFP32:$src), OneArgFP, []>;
407410 def IST_Fp16m80 : FpI_<(outs), (ins i16mem:$op, RFP80:$src), OneArgFP, []>;
408411 def IST_Fp32m80 : FpI_<(outs), (ins i32mem:$op, RFP80:$src), OneArgFP, []>;
409412 def IST_Fp64m80 : FpI_<(outs), (ins i64mem:$op, RFP80:$src), OneArgFP, []>;
410
413 }
414
415 let mayLoad = 1 in {
411416 def LD_F32m : FPI<0xD9, MRM0m, (outs), (ins f32mem:$src), "fld{s}\t$src">;
412417 def LD_F64m : FPI<0xDD, MRM0m, (outs), (ins f64mem:$src), "fld{l}\t$src">;
413418 def LD_F80m : FPI<0xDB, MRM5m, (outs), (ins f80mem:$src), "fld{t}\t$src">;
414419 def ILD_F16m : FPI<0xDF, MRM0m, (outs), (ins i16mem:$src), "fild{s}\t$src">;
415420 def ILD_F32m : FPI<0xDB, MRM0m, (outs), (ins i32mem:$src), "fild{l}\t$src">;
416421 def ILD_F64m : FPI<0xDF, MRM5m, (outs), (ins i64mem:$src), "fild{ll}\t$src">;
422 }
423 let mayStore = 1 in {
417424 def ST_F32m : FPI<0xD9, MRM2m, (outs), (ins f32mem:$dst), "fst{s}\t$dst">;
418425 def ST_F64m : FPI<0xDD, MRM2m, (outs), (ins f64mem:$dst), "fst{l}\t$dst">;
419426 def ST_FP32m : FPI<0xD9, MRM3m, (outs), (ins f32mem:$dst), "fstp{s}\t$dst">;
424431 def IST_FP16m : FPI<0xDF, MRM3m, (outs), (ins i16mem:$dst), "fistp{s}\t$dst">;
425432 def IST_FP32m : FPI<0xDB, MRM3m, (outs), (ins i32mem:$dst), "fistp{l}\t$dst">;
426433 def IST_FP64m : FPI<0xDF, MRM7m, (outs), (ins i64mem:$dst), "fistp{ll}\t$dst">;
434 }
427435
428436 // FISTTP requires SSE3 even though it's a FPStack op.
429437 def ISTT_Fp16m32 : FpI_<(outs), (ins i16mem:$op, RFP32:$src), OneArgFP,
454462 [(X86fp_to_i64mem RFP80:$src, addr:$op)]>,
455463 Requires<[HasSSE3]>;
456464
465 let mayStore = 1 in {
457466 def ISTT_FP16m : FPI<0xDF, MRM1m, (outs), (ins i16mem:$dst), "fisttp{s}\t$dst">;
458467 def ISTT_FP32m : FPI<0xDB, MRM1m, (outs), (ins i32mem:$dst), "fisttp{l}\t$dst">;
459468 def ISTT_FP64m : FPI<0xDD, MRM1m, (outs), (ins i64mem:$dst), "fisttp{ll}\t$dst">;
469 }
460470
461471 // FP Stack manipulation instructions.
462472 def LD_Frr : FPI<0xC0, AddRegFrm, (outs), (ins RST:$op), "fld\t$op">, D9;
530540 def FNSTCW16m : I<0xD9, MRM7m, // [mem16] = X87 control world
531541 (outs), (ins i16mem:$dst), "fnstcw\t$dst",
532542 [(X86fp_cwd_get16 addr:$dst)]>;
543
544 let mayLoad = 1 in
533545 def FLDCW16m : I<0xD9, MRM5m, // X87 control world = [mem16]
534546 (outs), (ins i16mem:$dst), "fldcw\t$dst", []>;
535547
9191 SDNPMayLoad]>;
9292
9393 def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG",SDTX86RdTsc,
94 [SDNPHasChain, SDNPOutFlag]>;
94 [SDNPHasChain, SDNPOutFlag, SDNPSideEffect]>;
9595
9696 def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
9797 def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>;
265265 def IMPLICIT_USE : I<0, Pseudo, (outs), (ins variable_ops),
266266 "#IMPLICIT_USE", []>;
267267 let isImplicitDef = 1 in {
268 let neverHasSideEffects = 1 in
268269 def IMPLICIT_DEF : I<0, Pseudo, (outs variable_ops), (ins),
269270 "#IMPLICIT_DEF", []>;
270271 def IMPLICIT_DEF_GR8 : I<0, Pseudo, (outs GR8:$dst), (ins),
279280 }
280281
281282 // Nop
282 def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", []>;
283 let neverHasSideEffects = 1 in
284 def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", []>;
283285
284286 // PIC base
285 let neverHasSideEffects = 1, isNotDuplicable = 1 in {
286 def MOVPC32r : Ii32<0xE8, Pseudo, (outs GR32:$reg), (ins piclabel:$label),
287 "call\t$label\n\tpop{l}\t$reg", []>;
288 }
287 let neverHasSideEffects = 1, isNotDuplicable = 1 in
288 def MOVPC32r : Ii32<0xE8, Pseudo, (outs GR32:$reg), (ins piclabel:$label),
289 "call\t$label\n\tpop{l}\t$reg", []>;
289290
290291 //===----------------------------------------------------------------------===//
291292 // Control Flow Instructions...
398399 //===----------------------------------------------------------------------===//
399400 // Miscellaneous Instructions...
400401 //
401 let Defs = [EBP, ESP], Uses = [EBP, ESP] in
402 let Defs = [EBP, ESP], Uses = [EBP, ESP], mayLoad = 1, neverHasSideEffects=1 in
402403 def LEAVE : I<0xC9, RawFrm,
403404 (outs), (ins), "leave", []>;
404405
405 let Defs = [ESP], Uses = [ESP] in {
406 let Defs = [ESP], Uses = [ESP], neverHasSideEffects=1 in {
407 let mayLoad = 1 in
406408 def POP32r : I<0x58, AddRegFrm, (outs GR32:$reg), (ins), "pop{l}\t$reg", []>;
407409
410 let mayStore = 1 in
408411 def PUSH32r : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[]>;
409412 }
410413
411 let Defs = [ESP, EFLAGS], Uses = [ESP] in
414 let Defs = [ESP, EFLAGS], Uses = [ESP], mayLoad = 1, neverHasSideEffects=1 in
412415 def POPFD : I<0x9D, RawFrm, (outs), (ins), "popf", []>;
413 let Defs = [ESP], Uses = [ESP, EFLAGS] in
416 let Defs = [ESP], Uses = [ESP, EFLAGS], mayStore = 1, neverHasSideEffects=1 in
414417 def PUSHFD : I<0x9C, RawFrm, (outs), (ins), "pushf", []>;
415418
416419 let isTwoAddress = 1 in // GR32 = bswap GR32
482485 (implicit EFLAGS)]>, TB;
483486 } // Defs = [EFLAGS]
484487
488 let neverHasSideEffects = 1 in
485489 def LEA16r : I<0x8D, MRMSrcMem,
486490 (outs GR16:$dst), (ins i32mem:$src),
487491 "lea{w}\t{$src|$dst}, {$dst|$src}", []>, OpSize;
559563 //===----------------------------------------------------------------------===//
560564 // Move Instructions...
561565 //
566 let neverHasSideEffects = 1 in {
562567 def MOV8rr : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src),
563568 "mov{b}\t{$src, $dst|$dst, $src}", []>;
564569 def MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
565570 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize;
566571 def MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
567572 "mov{l}\t{$src, $dst|$dst, $src}", []>;
573 }
568574 let isReMaterializable = 1 in {
569575 def MOV8ri : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src),
570576 "mov{b}\t{$src, $dst|$dst, $src}",
632638 // This probably ought to be moved to a def : Pat<> if the
633639 // syntax can be accepted.
634640 [(set AL, (mul AL, (loadi8 addr:$src)))]>; // AL,AH = AL*[mem8]
641 let mayLoad = 1, neverHasSideEffects = 1 in {
635642 let Defs = [AX,DX,EFLAGS], Uses = [AX] in
636643 def MUL16m : I<0xF7, MRM4m, (outs), (ins i16mem:$src),
637644 "mul{w}\t$src", []>, OpSize; // AX,DX = AX*[mem16]
638645 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
639646 def MUL32m : I<0xF7, MRM4m, (outs), (ins i32mem:$src),
640647 "mul{l}\t$src", []>; // EAX,EDX = EAX*[mem32]
641
648 }
649
650 let neverHasSideEffects = 1 in {
642651 let Defs = [AL,AH,EFLAGS], Uses = [AL] in
643652 def IMUL8r : I<0xF6, MRM5r, (outs), (ins GR8:$src), "imul{b}\t$src", []>;
644653 // AL,AH = AL*GR8
648657 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
649658 def IMUL32r : I<0xF7, MRM5r, (outs), (ins GR32:$src), "imul{l}\t$src", []>;
650659 // EAX,EDX = EAX*GR32
660 let mayLoad = 1 in {
651661 let Defs = [AL,AH,EFLAGS], Uses = [AL] in
652662 def IMUL8m : I<0xF6, MRM5m, (outs), (ins i8mem :$src),
653663 "imul{b}\t$src", []>; // AL,AH = AL*[mem8]
657667 let Defs = [EAX,EDX], Uses = [EAX] in
658668 def IMUL32m : I<0xF7, MRM5m, (outs), (ins i32mem:$src),
659669 "imul{l}\t$src", []>; // EAX,EDX = EAX*[mem32]
670 }
660671
661672 // unsigned division/remainder
662673 let Defs = [AX,EFLAGS], Uses = [AL,AH] in
668679 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
669680 def DIV32r : I<0xF7, MRM6r, (outs), (ins GR32:$src), // EDX:EAX/r32 = EAX,EDX
670681 "div{l}\t$src", []>;
682 let mayLoad = 1 in {
671683 let Defs = [AX,EFLAGS], Uses = [AL,AH] in
672684 def DIV8m : I<0xF6, MRM6m, (outs), (ins i8mem:$src), // AX/[mem8] = AL,AH
673685 "div{b}\t$src", []>;
677689 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
678690 def DIV32m : I<0xF7, MRM6m, (outs), (ins i32mem:$src), // EDX:EAX/[mem32] = EAX,EDX
679691 "div{l}\t$src", []>;
692 }
680693
681694 // Signed division/remainder.
682695 let Defs = [AX,EFLAGS], Uses = [AL,AH] in
688701 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
689702 def IDIV32r: I<0xF7, MRM7r, (outs), (ins GR32:$src), // EDX:EAX/r32 = EAX,EDX
690703 "idiv{l}\t$src", []>;
704 let mayLoad = 1, mayLoad = 1 in {
691705 let Defs = [AX,EFLAGS], Uses = [AL,AH] in
692706 def IDIV8m : I<0xF6, MRM7m, (outs), (ins i8mem:$src), // AX/[mem8] = AL,AH
693707 "idiv{b}\t$src", []>;
697711 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
698712 def IDIV32m: I<0xF7, MRM7m, (outs), (ins i32mem:$src), // EDX:EAX/[mem32] = EAX,EDX
699713 "idiv{l}\t$src", []>;
700
701
702 //===----------------------------------------------------------------------===//
703 // Two address Instructions...
714 }
715 } // neverHasSideEffects
716
717 //===----------------------------------------------------------------------===//
718 // Two address Instructions.
704719 //
705720 let isTwoAddress = 1 in {
706721
21602175
21612176
21622177 // Condition code ops, incl. set if equal/not equal/...
2163 let Defs = [EFLAGS], Uses = [AH] in
2178 let Defs = [EFLAGS], Uses = [AH], neverHasSideEffects = 1 in
21642179 def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf", []>; // flags = AH
2165 let Defs = [AH], Uses = [EFLAGS] in
2180 let Defs = [AH], Uses = [EFLAGS], neverHasSideEffects = 1 in
21662181 def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", []>; // AH = flags
21672182
21682183 let Uses = [EFLAGS] in {
24442459 "movz{wl|x}\t{$src, $dst|$dst, $src}",
24452460 [(set GR32:$dst, (zextloadi32i16 addr:$src))]>, TB;
24462461
2447 let Defs = [AX], Uses = [AL] in
2448 def CBW : I<0x98, RawFrm, (outs), (ins),
2449 "{cbtw|cbw}", []>, OpSize; // AX = signext(AL)
2450 let Defs = [EAX], Uses = [AX] in
2451 def CWDE : I<0x98, RawFrm, (outs), (ins),
2452 "{cwtl|cwde}", []>; // EAX = signext(AX)
2453
2454 let Defs = [AX,DX], Uses = [AX] in
2455 def CWD : I<0x99, RawFrm, (outs), (ins),
2456 "{cwtd|cwd}", []>, OpSize; // DX:AX = signext(AX)
2457 let Defs = [EAX,EDX], Uses = [EAX] in
2458 def CDQ : I<0x99, RawFrm, (outs), (ins),
2459 "{cltd|cdq}", []>; // EDX:EAX = signext(EAX)
2460
2462 let neverHasSideEffects = 1 in {
2463 let Defs = [AX], Uses = [AL] in
2464 def CBW : I<0x98, RawFrm, (outs), (ins),
2465 "{cbtw|cbw}", []>, OpSize; // AX = signext(AL)
2466 let Defs = [EAX], Uses = [AX] in
2467 def CWDE : I<0x98, RawFrm, (outs), (ins),
2468 "{cwtl|cwde}", []>; // EAX = signext(AX)
2469
2470 let Defs = [AX,DX], Uses = [AX] in
2471 def CWD : I<0x99, RawFrm, (outs), (ins),
2472 "{cwtd|cwd}", []>, OpSize; // DX:AX = signext(AX)
2473 let Defs = [EAX,EDX], Uses = [EAX] in
2474 def CDQ : I<0x99, RawFrm, (outs), (ins),
2475 "{cltd|cdq}", []>; // EDX:EAX = signext(EAX)
2476 }
24612477
24622478 //===----------------------------------------------------------------------===//
24632479 // Alias Instructions
24792495
24802496 // Basic operations on GR16 / GR32 subclasses GR16_ and GR32_ which contains only
24812497 // those registers that have GR8 sub-registers (i.e. AX - DX, EAX - EDX).
2498 let neverHasSideEffects = 1 in {
24822499 def MOV16to16_ : I<0x89, MRMDestReg, (outs GR16_:$dst), (ins GR16:$src),
24832500 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize;
24842501 def MOV32to32_ : I<0x89, MRMDestReg, (outs GR32_:$dst), (ins GR32:$src),
24852502 "mov{l}\t{$src, $dst|$dst, $src}", []>;
2486
2503
24872504 def MOV16_rr : I<0x89, MRMDestReg, (outs GR16_:$dst), (ins GR16_:$src),
24882505 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize;
24892506 def MOV32_rr : I<0x89, MRMDestReg, (outs GR32_:$dst), (ins GR32_:$src),
24902507 "mov{l}\t{$src, $dst|$dst, $src}", []>;
2491 let isSimpleLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
2508 } // neverHasSideEffects
2509
2510 let isSimpleLoad = 1, mayLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
24922511 def MOV16_rm : I<0x8B, MRMSrcMem, (outs GR16_:$dst), (ins i16mem:$src),
24932512 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize;
24942513 def MOV32_rm : I<0x8B, MRMSrcMem, (outs GR32_:$dst), (ins i32mem:$src),
24952514 "mov{l}\t{$src, $dst|$dst, $src}", []>;
24962515 }
2516 let mayStore = 1, neverHasSideEffects = 1 in {
24972517 def MOV16_mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16_:$src),
24982518 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize;
24992519 def MOV32_mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32_:$src),
25002520 "mov{l}\t{$src, $dst|$dst, $src}", []>;
2521 }
25012522
25022523 //===----------------------------------------------------------------------===//
25032524 // Thread Local Storage Instructions
155155 //===----------------------------------------------------------------------===//
156156
157157 // Data Transfer Instructions
158 let neverHasSideEffects = 1 in
158159 def MMX_MOVD64rr : MMXI<0x6E, MRMSrcReg, (outs VR64:$dst), (ins GR32:$src),
159160 "movd\t{$src, $dst|$dst, $src}", []>;
160 let isSimpleLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
161 let isSimpleLoad = 1, mayLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
161162 def MMX_MOVD64rm : MMXI<0x6E, MRMSrcMem, (outs VR64:$dst), (ins i32mem:$src),
162163 "movd\t{$src, $dst|$dst, $src}", []>;
164 let mayStore = 1 in
163165 def MMX_MOVD64mr : MMXI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, VR64:$src),
164166 "movd\t{$src, $dst|$dst, $src}", []>;
165167
168 let neverHasSideEffects = 1 in
166169 def MMX_MOVD64to64rr : MMXRI<0x6E, MRMSrcReg, (outs VR64:$dst), (ins GR64:$src),
167170 "movd\t{$src, $dst|$dst, $src}", []>;
168171
172 let neverHasSideEffects = 1 in
169173 def MMX_MOVQ64rr : MMXI<0x6F, MRMSrcReg, (outs VR64:$dst), (ins VR64:$src),
170174 "movq\t{$src, $dst|$dst, $src}", []>;
171175 let isSimpleLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
416420 MMX_PSHUFW_shuffle_mask:$src2)))]>;
417421
418422 // -- Conversion Instructions
423 let neverHasSideEffects = 1 in {
419424 def MMX_CVTPD2PIrr : MMX2I<0x2D, MRMSrcReg, (outs VR64:$dst), (ins VR128:$src),
420425 "cvtpd2pi\t{$src, $dst|$dst, $src}", []>;
426 let mayLoad = 1 in
421427 def MMX_CVTPD2PIrm : MMX2I<0x2D, MRMSrcMem, (outs VR64:$dst), (ins f128mem:$src),
422428 "cvtpd2pi\t{$src, $dst|$dst, $src}", []>;
423429
424430 def MMX_CVTPI2PDrr : MMX2I<0x2A, MRMSrcReg, (outs VR128:$dst), (ins VR64:$src),
425431 "cvtpi2pd\t{$src, $dst|$dst, $src}", []>;
432 let mayLoad = 1 in
426433 def MMX_CVTPI2PDrm : MMX2I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
427434 "cvtpi2pd\t{$src, $dst|$dst, $src}", []>;
428435
429436 def MMX_CVTPI2PSrr : MMXI<0x2A, MRMSrcReg, (outs VR128:$dst), (ins VR64:$src),
430437 "cvtpi2ps\t{$src, $dst|$dst, $src}", []>;
438 let mayLoad = 1 in
431439 def MMX_CVTPI2PSrm : MMXI<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
432440 "cvtpi2ps\t{$src, $dst|$dst, $src}", []>;
433441
434442 def MMX_CVTPS2PIrr : MMXI<0x2D, MRMSrcReg, (outs VR64:$dst), (ins VR128:$src),
435443 "cvtps2pi\t{$src, $dst|$dst, $src}", []>;
444 let mayLoad = 1 in
436445 def MMX_CVTPS2PIrm : MMXI<0x2D, MRMSrcMem, (outs VR64:$dst), (ins f64mem:$src),
437446 "cvtps2pi\t{$src, $dst|$dst, $src}", []>;
438447
439448 def MMX_CVTTPD2PIrr : MMX2I<0x2C, MRMSrcReg, (outs VR64:$dst), (ins VR128:$src),
440449 "cvttpd2pi\t{$src, $dst|$dst, $src}", []>;
450 let mayLoad = 1 in
441451 def MMX_CVTTPD2PIrm : MMX2I<0x2C, MRMSrcMem, (outs VR64:$dst), (ins f128mem:$src),
442452 "cvttpd2pi\t{$src, $dst|$dst, $src}", []>;
443453
444454 def MMX_CVTTPS2PIrr : MMXI<0x2C, MRMSrcReg, (outs VR64:$dst), (ins VR128:$src),
445455 "cvttps2pi\t{$src, $dst|$dst, $src}", []>;
456 let mayLoad = 1 in
446457 def MMX_CVTTPS2PIrm : MMXI<0x2C, MRMSrcMem, (outs VR64:$dst), (ins f64mem:$src),
447458 "cvttps2pi\t{$src, $dst|$dst, $src}", []>;
459 } // end neverHasSideEffects
460
448461
449462 // Extract / Insert
450463 def MMX_X86pextrw : SDNode<"X86ISD::PEXTRW", SDTypeProfile<1, 2, []>, []>;
4141 // SSE 'Special' Instructions
4242 //===----------------------------------------------------------------------===//
4343
44 let isImplicitDef = 1 in
44 let isImplicitDef = 1 in {
4545 def IMPLICIT_DEF_VR128 : I<0, Pseudo, (outs VR128:$dst), (ins),
4646 "#IMPLICIT_DEF $dst",
4747 [(set VR128:$dst, (v4f32 (undef)))]>,
5252 def IMPLICIT_DEF_FR64 : I<0, Pseudo, (outs FR64:$dst), (ins),
5353 "#IMPLICIT_DEF $dst",
5454 [(set FR64:$dst, (undef))]>, Requires<[HasSSE2]>;
55 }
5556
5657 //===----------------------------------------------------------------------===//
5758 // SSE Complex Patterns
6162 // the top elements. These are used for the SSE 'ss' and 'sd' instruction
6263 // forms.
6364 def sse_load_f32 : ComplexPattern
64 [SDNPHasChain]>;
65 [SDNPHasChain, SDNPMayLoad]>;
6566 def sse_load_f64 : ComplexPattern
66 [SDNPHasChain]>;
67 [SDNPHasChain, SDNPMayLoad]>;
6768
6869 def ssmem : Operand {
6970 let PrintMethod = "printf32mem";
451452
452453 // Alias instruction to do FR32 reg-to-reg copy using movaps. Upper bits are
453454 // disregarded.
455 let neverHasSideEffects = 1 in
454456 def FsMOVAPSrr : PSI<0x28, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
455457 "movaps\t{$src, $dst|$dst, $src}", []>;
456458
487489 "xorps\t{$src2, $dst|$dst, $src2}",
488490 [(set FR32:$dst, (X86fxor FR32:$src1,
489491 (memopfsf32 addr:$src2)))]>;
490
492 let neverHasSideEffects = 1 in {
491493 def FsANDNPSrr : PSI<0x55, MRMSrcReg,
492494 (outs FR32:$dst), (ins FR32:$src1, FR32:$src2),
493495 "andnps\t{$src2, $dst|$dst, $src2}", []>;
496
497 let mayLoad = 1 in
494498 def FsANDNPSrm : PSI<0x55, MRMSrcMem,
495499 (outs FR32:$dst), (ins FR32:$src1, f128mem:$src2),
496500 "andnps\t{$src2, $dst|$dst, $src2}", []>;
501 }
497502 }
498503
499504 /// basic_sse1_fp_binop_rm - SSE1 binops come in both scalar and vector forms.
631636 // SSE packed FP Instructions
632637
633638 // Move Instructions
639 let neverHasSideEffects = 1 in
634640 def MOVAPSrr : PSI<0x28, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
635641 "movaps\t{$src, $dst|$dst, $src}", []>;
636642 let isSimpleLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
11471153
11481154 // Alias instruction to do FR64 reg-to-reg copy using movapd. Upper bits are
11491155 // disregarded.
1156 let neverHasSideEffects = 1 in
11501157 def FsMOVAPDrr : PDI<0x28, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
11511158 "movapd\t{$src, $dst|$dst, $src}", []>;
11521159
11841191 [(set FR64:$dst, (X86fxor FR64:$src1,
11851192 (memopfsf64 addr:$src2)))]>;
11861193
1194 let neverHasSideEffects = 1 in {
11871195 def FsANDNPDrr : PDI<0x55, MRMSrcReg,
11881196 (outs FR64:$dst), (ins FR64:$src1, FR64:$src2),
11891197 "andnpd\t{$src2, $dst|$dst, $src2}", []>;
1198 let mayLoad = 1 in
11901199 def FsANDNPDrm : PDI<0x55, MRMSrcMem,
11911200 (outs FR64:$dst), (ins FR64:$src1, f128mem:$src2),
11921201 "andnpd\t{$src2, $dst|$dst, $src2}", []>;
1202 }
11931203 }
11941204
11951205 /// basic_sse2_fp_binop_rm - SSE2 binops come in both scalar and vector forms.
13271337 // SSE packed FP Instructions
13281338
13291339 // Move Instructions
1340 let neverHasSideEffects = 1 in
13301341 def MOVAPDrr : PDI<0x28, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
13311342 "movapd\t{$src, $dst|$dst, $src}", []>;
13321343 let isSimpleLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
21162127 def MFENCE : I<0xAE, MRM6m, (outs), (ins),
21172128 "mfence", [(int_x86_sse2_mfence)]>, TB, Requires<[HasSSE2]>;
21182129
2119
21202130 // Alias instructions that map zero vector to pxor / xorp* for sse.
21212131 let isReMaterializable = 1 in
21222132 def V_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins),
9696 usesCustomDAGSchedInserter = R->getValueAsBit("usesCustomDAGSchedInserter");
9797 hasCtrlDep = R->getValueAsBit("hasCtrlDep");
9898 isNotDuplicable = R->getValueAsBit("isNotDuplicable");
99 hasSideEffects = R->getValueAsBit("hasSideEffects");
99100 mayHaveSideEffects = R->getValueAsBit("mayHaveSideEffects");
100101 neverHasSideEffects = R->getValueAsBit("neverHasSideEffects");
101102 hasOptionalDef = false;
102103 isVariadic = false;
103104
104 if (mayHaveSideEffects && neverHasSideEffects)
105 throw R->getName() +
106 ": cannot have both 'mayHaveSideEffects' and 'neverHasSideEffects' set!";
105 if (mayHaveSideEffects + neverHasSideEffects + hasSideEffects > 1)
106 throw R->getName() + ": multiple conflicting side-effect flags set!";
107107
108108 DagInit *DI;
109109 try {
102102 bool hasCtrlDep;
103103 bool isNotDuplicable;
104104 bool hasOptionalDef;
105 bool mayHaveSideEffects;
106 bool neverHasSideEffects;
105 bool hasSideEffects, mayHaveSideEffects, neverHasSideEffects;
107106
108107 /// ParseOperandName - Parse an operand name like "$foo" or "$foo.bar",
109108 /// where $foo is a whole operand and $foo.bar refers to a suboperand.
339339 Properties |= 1 << SDNPHasChain;
340340 } else if (PropList[i]->getName() == "SDNPOptInFlag") {
341341 Properties |= 1 << SDNPOptInFlag;
342 } else if (PropList[i]->getName() == "SDNPMayStore") {
343 Properties |= 1 << SDNPMayStore;
344 } else if (PropList[i]->getName() == "SDNPMayLoad") {
345 Properties |= 1 << SDNPMayLoad;
346 } else if (PropList[i]->getName() == "SDNPSideEffect") {
347 Properties |= 1 << SDNPSideEffect;
342348 } else {
343349 cerr << "Unsupported SD Node property '" << PropList[i]->getName()
344350 << "' on ComplexPattern '" << R->getName() << "'!\n";
151151 : CDP(cdp), mayStore(maystore), mayLoad(mayload), HasSideEffects(hse){
152152 }
153153
154 void Analyze(Record *InstRecord) {
154 /// Analyze - Analyze the specified instruction, returning true if the
155 /// instruction had a pattern.
156 bool Analyze(Record *InstRecord) {
155157 const TreePattern *Pattern = CDP.getInstruction(InstRecord).getPattern();
156158 if (Pattern == 0) {
157159 HasSideEffects = 1;
158 return; // No pattern.
160 return false; // No pattern.
159161 }
160162
161163 // FIXME: Assume only the first tree is the pattern. The others are clobber
162164 // nodes.
163165 AnalyzeNode(Pattern->getTree(0));
166 return true;
164167 }
165168
166169 private:
167170 void AnalyzeNode(const TreePatternNode *N) {
168 if (N->isLeaf())
171 if (N->isLeaf()) {
172 if (DefInit *DI = dynamic_cast(N->getLeafValue())) {
173 Record *LeafRec = DI->getDef();
174 // Handle ComplexPattern leaves.
175 if (LeafRec->isSubClassOf("ComplexPattern")) {
176 const ComplexPattern &CP = CDP.getComplexPattern(LeafRec);
177 if (CP.hasProperty(SDNPMayStore)) mayStore = true;
178 if (CP.hasProperty(SDNPMayLoad)) mayLoad = true;
179 if (CP.hasProperty(SDNPSideEffect)) HasSideEffects = true;
180 }
181 }
169182 return;
183 }
170184
171185 // Analyze children.
172186 for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
179193 // Get information about the SDNode for the operator.
180194 const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator());
181195
182 // If node writes to memory, it obviously stores to memory.
183 if (OpInfo.hasProperty(SDNPMayStore))
184 mayStore = true;
185
186 // If it reads memory, remember this.
187 if (OpInfo.hasProperty(SDNPMayLoad))
188 mayLoad = true;
189
190 // If it reads memory, remember this.
191 if (OpInfo.hasProperty(SDNPSideEffect))
192 HasSideEffects = true;
196 // Notice properties of the node.
197 if (OpInfo.hasProperty(SDNPMayStore)) mayStore = true;
198 if (OpInfo.hasProperty(SDNPMayLoad)) mayLoad = true;
199 if (OpInfo.hasProperty(SDNPSideEffect)) HasSideEffects = true;
193200
194201 if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) {
195202 // If this is an intrinsic, analyze it.
212219 bool &HasSideEffects) {
213220 MayStore = MayLoad = HasSideEffects = false;
214221
215 InstAnalyzer(CDP, MayStore, MayLoad, HasSideEffects).Analyze(Inst.TheDef);
222 bool HadPattern =
223 InstAnalyzer(CDP, MayStore, MayLoad, HasSideEffects).Analyze(Inst.TheDef);
216224
217225 // InstAnalyzer only correctly analyzes mayStore/mayLoad so far.
218226 if (Inst.mayStore) { // If the .td file explicitly sets mayStore, use it.
238246 }
239247
240248 if (Inst.neverHasSideEffects) {
241 // If we already decided that this instruction has no side effects, then the
242 // .td file entry is redundant.
243 if (!HasSideEffects)
244 fprintf(stderr,
245 "Warning: neverHasSideEffects flag explicitly set on instruction"
246 " '%s' but flag already inferred from pattern.\n",
247 Inst.TheDef->getName().c_str());
249 if (HadPattern)
250 fprintf(stderr, "Warning: neverHasSideEffects set on instruction '%s' "
251 "which already has a pattern\n", Inst.TheDef->getName().c_str());
248252 HasSideEffects = false;
253 }
254
255 if (Inst.hasSideEffects) {
256 if (HasSideEffects)
257 fprintf(stderr, "Warning: hasSideEffects set on instruction '%s' "
258 "which already inferred this.\n", Inst.TheDef->getName().c_str());
259 HasSideEffects = true;
249260 }
250261 }
251262